public SecurityToken mapSignInResponse()

in services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/protocols/TrustedIdpOIDCProtocolHandler.java [107:241]


    public SecurityToken mapSignInResponse(RequestContext context, Idp idp, TrustedIdp trustedIdp) {

        String code = (String) WebUtils.getAttributeFromFlowScope(context,
                                                                  OAuthConstants.CODE_RESPONSE_TYPE);
        if (code != null && !code.isEmpty()) {

            String tokenEndpoint = getProperty(trustedIdp, TOKEN_ENDPOINT);
            if (tokenEndpoint == null || tokenEndpoint.isEmpty()) {
                LOG.warn("A TOKEN_ENDPOINT must be configured to use the OIDCProtocolHandler");
                throw new IllegalStateException("No TOKEN_ENDPOINT specified");
            }

            String clientId = getProperty(trustedIdp, CLIENT_ID);
            String clientSecret = getProperty(trustedIdp, CLIENT_SECRET);
            if (clientSecret == null || clientSecret.isEmpty()) {
                LOG.warn("A CLIENT_SECRET must be configured to use the OIDCProtocolHandler");
                throw new IllegalStateException("No CLIENT_SECRET specified");
            }

            // Here we need to get the IdToken using the authorization code
            List<Object> providers = new ArrayList<>();
            providers.add(new OAuthJSONProvider());

            WebClient client =
                WebClient.create(tokenEndpoint, providers, clientId, clientSecret, "cxf-tls.xml");

            if (LOG.isDebugEnabled()) {
                ClientConfiguration config = WebClient.getConfig(client);
                config.getOutInterceptors().add(new LoggingOutInterceptor());
                config.getInInterceptors().add(new LoggingInInterceptor());
            }

            client.type("application/x-www-form-urlencoded").accept("application/json");

            Form form = new Form();
            form.param("grant_type", "authorization_code");
            form.param("code", code);
            form.param("client_id", clientId);
            form.param("redirect_uri", idp.getIdpUrl().toString());
            Response response = client.post(form);

            ClientAccessToken accessToken = response.readEntity(ClientAccessToken.class);
            String idToken = accessToken.getParameters().get("id_token");
            if (idToken == null) {
                LOG.warn("No IdToken received from the OIDC IdP");
                return null;
            }

            client.close();

            try {
                String whr = (String) WebUtils.getAttributeFromFlowScope(context, IdpConstants.HOME_REALM);
                if (whr == null) {
                    LOG.warn("Home realm is null");
                    throw new IllegalStateException("Home realm is null");
                }

                // Parse the received Token
                JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(idToken);
                JwtToken jwt = jwtConsumer.getJwtToken();

                if (LOG.isDebugEnabled()) {
                    if (jwt.getClaims() != null) {
                        LOG.debug("Received Claims:");
                        for (Map.Entry<String, Object> claim : jwt.getClaims().asMap().entrySet()) {
                            LOG.debug(claim.getKey() + ": " + claim.getValue());
                        }
                    }

                    if (jwt.getJwsHeaders() != null) {
                        LOG.debug("Received JWS Headers:");
                        for (Map.Entry<String, Object> header : jwt.getJwsHeaders().asMap().entrySet()) {
                            LOG.debug(header.getKey() + ": " + header.getValue());
                        }
                    }
                }

                if (!validateSignature(trustedIdp, jwtConsumer)) {
                    LOG.warn("Signature does not validate");
                    return null;
                }

                // Make sure the received token is valid according to the spec
                validateToken(jwt, clientId);

                Instant created = Instant.ofEpochSecond((long)jwt.getClaim(JwtConstants.CLAIM_ISSUED_AT));
                Instant notBefore = null;
                if (jwt.getClaim(JwtConstants.CLAIM_NOT_BEFORE) != null) {
                    notBefore = Instant.ofEpochSecond((long)jwt.getClaim(JwtConstants.CLAIM_NOT_BEFORE));
                }

                Instant expires = Instant.ofEpochSecond((long)jwt.getClaim(JwtConstants.CLAIM_EXPIRY));

                // Subject
                String subjectName = getProperty(trustedIdp, SUBJECT_CLAIM);
                LOG.debug("Trying to extract subject name using the claim name {}", subjectName);
                if (subjectName == null || jwt.getClaim(subjectName) == null) {
                    LOG.debug("No claim available in the token for {}", subjectName);
                    subjectName = "preferred_username";
                    LOG.debug("Falling back to use subject claim name {}", subjectName);
                    if (jwt.getClaim(subjectName) == null) {
                        subjectName = JwtConstants.CLAIM_SUBJECT;
                        LOG.debug("No claim available in the token for preferred_username. "
                                  + "Falling back to use {}", subjectName);
                    }
                }

                // Convert into a SAML Token
                SamlAssertionWrapper assertion =
                    createSamlAssertion(idp, trustedIdp, jwt.getClaims(), (String)jwt.getClaim(subjectName), 
                                        notBefore, expires);
                Document doc = DOMUtils.createDocument();
                Element token = assertion.toDOM(doc);

                // Create new Security token with new id.
                // Parameters for freshness computation are copied from original IDP_TOKEN
                SecurityToken idpToken = new SecurityToken(assertion.getId(), created, expires);
                idpToken.setToken(token);

                LOG.info("[IDP_TOKEN={}] for user '{}' created from [RP_TOKEN={}] issued by home realm [{}/{}]",
                         assertion.getId(), assertion.getSaml2().getSubject().getNameID().getValue(),
                         jwt.getClaim(JwtConstants.CLAIM_JWT_ID), whr, jwt.getClaim(JwtConstants.CLAIM_ISSUER));
                LOG.debug("Created date={}", created);
                LOG.debug("Expired date={}", expires);

                return idpToken;
            } catch (IllegalStateException ex) {
                throw ex;
            } catch (Exception ex) {
                LOG.warn("Unexpected exception occured", ex);
                throw new IllegalStateException("Unexpected exception occured: " + ex.getMessage());
            }
        }
        return null;
    }