Search in sources :

Example 1 with JWT

use of com.nimbusds.jwt.JWT in project pac4j by pac4j.

the class JwtAuthenticator method validate.

@Override
public void validate(final TokenCredentials credentials, final WebContext context) {
    init();
    final String token = credentials.getToken();
    if (context != null) {
        // set the www-authenticate in case of error
        context.setResponseHeader(HttpConstants.AUTHENTICATE_HEADER, "Bearer realm=\"" + realmName + "\"");
    }
    try {
        // Parse the token
        JWT jwt = JWTParser.parse(token);
        if (jwt instanceof PlainJWT) {
            if (signatureConfigurations.isEmpty()) {
                logger.debug("JWT is not signed and no signature configurations -> verified");
            } else {
                throw new CredentialsException("A non-signed JWT cannot be accepted as signature configurations have been defined");
            }
        } else {
            SignedJWT signedJWT = null;
            if (jwt instanceof SignedJWT) {
                signedJWT = (SignedJWT) jwt;
            }
            // encrypted?
            if (jwt instanceof EncryptedJWT) {
                logger.debug("JWT is encrypted");
                final EncryptedJWT encryptedJWT = (EncryptedJWT) jwt;
                boolean found = false;
                final JWEHeader header = encryptedJWT.getHeader();
                final JWEAlgorithm algorithm = header.getAlgorithm();
                final EncryptionMethod method = header.getEncryptionMethod();
                for (final EncryptionConfiguration config : encryptionConfigurations) {
                    if (config.supports(algorithm, method)) {
                        logger.debug("Using encryption configuration: {}", config);
                        try {
                            config.decrypt(encryptedJWT);
                            signedJWT = encryptedJWT.getPayload().toSignedJWT();
                            if (signedJWT != null) {
                                jwt = signedJWT;
                            }
                            found = true;
                            break;
                        } catch (final JOSEException e) {
                            logger.debug("Decryption fails with encryption configuration: {}, passing to the next one", config);
                        }
                    }
                }
                if (!found) {
                    throw new CredentialsException("No encryption algorithm found for JWT: " + token);
                }
            }
            // signed?
            if (signedJWT != null) {
                logger.debug("JWT is signed");
                boolean verified = false;
                boolean found = false;
                final JWSAlgorithm algorithm = signedJWT.getHeader().getAlgorithm();
                for (final SignatureConfiguration config : signatureConfigurations) {
                    if (config.supports(algorithm)) {
                        logger.debug("Using signature configuration: {}", config);
                        try {
                            verified = config.verify(signedJWT);
                            found = true;
                            if (verified) {
                                break;
                            }
                        } catch (final JOSEException e) {
                            logger.debug("Verification fails with signature configuration: {}, passing to the next one", config);
                        }
                    }
                }
                if (!found) {
                    throw new CredentialsException("No signature algorithm found for JWT: " + token);
                }
                if (!verified) {
                    throw new CredentialsException("JWT verification failed: " + token);
                }
            }
        }
        createJwtProfile(credentials, jwt);
    } catch (final ParseException e) {
        throw new CredentialsException("Cannot decrypt / verify JWT", e);
    }
}
Also used : PlainJWT(com.nimbusds.jwt.PlainJWT) SignatureConfiguration(org.pac4j.jwt.config.signature.SignatureConfiguration) EncryptionConfiguration(org.pac4j.jwt.config.encryption.EncryptionConfiguration) PlainJWT(com.nimbusds.jwt.PlainJWT) JWT(com.nimbusds.jwt.JWT) SignedJWT(com.nimbusds.jwt.SignedJWT) EncryptedJWT(com.nimbusds.jwt.EncryptedJWT) SignedJWT(com.nimbusds.jwt.SignedJWT) EncryptionMethod(com.nimbusds.jose.EncryptionMethod) CredentialsException(org.pac4j.core.exception.CredentialsException) JWSAlgorithm(com.nimbusds.jose.JWSAlgorithm) JWEHeader(com.nimbusds.jose.JWEHeader) JWEAlgorithm(com.nimbusds.jose.JWEAlgorithm) ParseException(java.text.ParseException) EncryptedJWT(com.nimbusds.jwt.EncryptedJWT) JOSEException(com.nimbusds.jose.JOSEException)

Example 2 with JWT

use of com.nimbusds.jwt.JWT in project pac4j by pac4j.

the class OidcExtractor method extract.

@Override
public OidcCredentials extract(final WebContext context) {
    final String computedCallbackUrl = client.computeFinalCallbackUrl(context);
    final Map<String, String> parameters = retrieveParameters(context);
    AuthenticationResponse response;
    try {
        response = AuthenticationResponseParser.parse(new URI(computedCallbackUrl), parameters);
    } catch (final URISyntaxException | ParseException e) {
        throw new TechnicalException(e);
    }
    if (response instanceof AuthenticationErrorResponse) {
        logger.error("Bad authentication response, error={}", ((AuthenticationErrorResponse) response).getErrorObject());
        return null;
    }
    logger.debug("Authentication response successful");
    AuthenticationSuccessResponse successResponse = (AuthenticationSuccessResponse) response;
    final State state = successResponse.getState();
    if (state == null) {
        throw new TechnicalException("Missing state parameter");
    }
    if (!state.equals(context.getSessionStore().get(context, OidcConfiguration.STATE_SESSION_ATTRIBUTE))) {
        throw new TechnicalException("State parameter is different from the one sent in authentication request. " + "Session expired or possible threat of cross-site request forgery");
    }
    final OidcCredentials credentials = new OidcCredentials();
    // get authorization code
    final AuthorizationCode code = successResponse.getAuthorizationCode();
    if (code != null) {
        credentials.setCode(code);
    }
    // get ID token
    final JWT idToken = successResponse.getIDToken();
    if (idToken != null) {
        credentials.setIdToken(idToken);
    }
    // get access token
    final AccessToken accessToken = successResponse.getAccessToken();
    if (accessToken != null) {
        credentials.setAccessToken(accessToken);
    }
    return credentials;
}
Also used : AuthorizationCode(com.nimbusds.oauth2.sdk.AuthorizationCode) TechnicalException(org.pac4j.core.exception.TechnicalException) JWT(com.nimbusds.jwt.JWT) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) OidcCredentials(org.pac4j.oidc.credentials.OidcCredentials) State(com.nimbusds.oauth2.sdk.id.State) AccessToken(com.nimbusds.oauth2.sdk.token.AccessToken) ParseException(com.nimbusds.oauth2.sdk.ParseException)

Example 3 with JWT

use of com.nimbusds.jwt.JWT in project pac4j by pac4j.

the class OidcProfileCreator method create.

@Override
@SuppressWarnings("unchecked")
public U create(final OidcCredentials credentials, final WebContext context) {
    init();
    final AccessToken accessToken = credentials.getAccessToken();
    // Create profile
    final U profile = getProfileDefinition().newProfile();
    profile.setAccessToken(accessToken);
    final JWT idToken = credentials.getIdToken();
    profile.setIdTokenString(idToken.getParsedString());
    // Check if there is a refresh token
    final RefreshToken refreshToken = credentials.getRefreshToken();
    if (refreshToken != null && !refreshToken.getValue().isEmpty()) {
        profile.setRefreshToken(refreshToken);
        logger.debug("Refresh Token successful retrieved");
    }
    try {
        // check idToken
        final Nonce nonce;
        if (configuration.isUseNonce()) {
            nonce = new Nonce((String) context.getSessionStore().get(context, OidcConfiguration.NONCE_SESSION_ATTRIBUTE));
        } else {
            nonce = null;
        }
        // Check ID Token
        final IDTokenClaimsSet claimsSet = this.idTokenValidator.validate(idToken, nonce);
        assertNotNull("claimsSet", claimsSet);
        profile.setId(ProfileHelper.sanitizeIdentifier(profile, claimsSet.getSubject()));
        // User Info request
        if (configuration.findProviderMetadata().getUserInfoEndpointURI() != null && accessToken != null) {
            final UserInfoRequest userInfoRequest = new UserInfoRequest(configuration.findProviderMetadata().getUserInfoEndpointURI(), (BearerAccessToken) accessToken);
            final HTTPRequest userInfoHttpRequest = userInfoRequest.toHTTPRequest();
            userInfoHttpRequest.setConnectTimeout(configuration.getConnectTimeout());
            userInfoHttpRequest.setReadTimeout(configuration.getReadTimeout());
            final HTTPResponse httpResponse = userInfoHttpRequest.send();
            logger.debug("Token response: status={}, content={}", httpResponse.getStatusCode(), httpResponse.getContent());
            final UserInfoResponse userInfoResponse = UserInfoResponse.parse(httpResponse);
            if (userInfoResponse instanceof UserInfoErrorResponse) {
                logger.error("Bad User Info response, error={}", ((UserInfoErrorResponse) userInfoResponse).getErrorObject());
            } else {
                final UserInfoSuccessResponse userInfoSuccessResponse = (UserInfoSuccessResponse) userInfoResponse;
                final JWTClaimsSet userInfoClaimsSet;
                if (userInfoSuccessResponse.getUserInfo() != null) {
                    userInfoClaimsSet = userInfoSuccessResponse.getUserInfo().toJWTClaimsSet();
                } else {
                    userInfoClaimsSet = userInfoSuccessResponse.getUserInfoJWT().getJWTClaimsSet();
                }
                getProfileDefinition().convertAndAdd(profile, userInfoClaimsSet.getClaims(), null);
            }
        }
        // add attributes of the ID token if they don't already exist
        for (final Map.Entry<String, Object> entry : idToken.getJWTClaimsSet().getClaims().entrySet()) {
            final String key = entry.getKey();
            final Object value = entry.getValue();
            // it's not the subject and this attribute does not already exist, add it
            if (!JwtClaims.SUBJECT.equals(key) && profile.getAttribute(key) == null) {
                getProfileDefinition().convertAndAdd(profile, PROFILE_ATTRIBUTE, key, value);
            }
        }
        return profile;
    } catch (final IOException | ParseException | JOSEException | BadJOSEException | java.text.ParseException e) {
        throw new TechnicalException(e);
    }
}
Also used : HTTPRequest(com.nimbusds.oauth2.sdk.http.HTTPRequest) TechnicalException(org.pac4j.core.exception.TechnicalException) JWT(com.nimbusds.jwt.JWT) HTTPResponse(com.nimbusds.oauth2.sdk.http.HTTPResponse) IDTokenClaimsSet(com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet) IOException(java.io.IOException) RefreshToken(com.nimbusds.oauth2.sdk.token.RefreshToken) BadJOSEException(com.nimbusds.jose.proc.BadJOSEException) AccessToken(com.nimbusds.oauth2.sdk.token.AccessToken) BearerAccessToken(com.nimbusds.oauth2.sdk.token.BearerAccessToken) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) ParseException(com.nimbusds.oauth2.sdk.ParseException) Map(java.util.Map) JOSEException(com.nimbusds.jose.JOSEException) BadJOSEException(com.nimbusds.jose.proc.BadJOSEException)

Example 4 with JWT

use of com.nimbusds.jwt.JWT in project spring-security by spring-projects.

the class NimbusJwtDecoder method decode.

/**
 * Decode and validate the JWT from its compact claims representation format
 * @param token the JWT value
 * @return a validated {@link Jwt}
 * @throws JwtException
 */
@Override
public Jwt decode(String token) throws JwtException {
    JWT jwt = parse(token);
    if (jwt instanceof PlainJWT) {
        this.logger.trace("Failed to decode unsigned token");
        throw new BadJwtException("Unsupported algorithm of " + jwt.getHeader().getAlgorithm());
    }
    Jwt createdJwt = createJwt(token, jwt);
    return validateJwt(createdJwt);
}
Also used : PlainJWT(com.nimbusds.jwt.PlainJWT) PlainJWT(com.nimbusds.jwt.PlainJWT) JWT(com.nimbusds.jwt.JWT)

Example 5 with JWT

use of com.nimbusds.jwt.JWT in project spring-security by spring-projects.

the class NimbusJwtDecoder method createJwt.

private Jwt createJwt(String token, JWT parsedJwt) {
    try {
        // Verify the signature
        JWTClaimsSet jwtClaimsSet = this.jwtProcessor.process(parsedJwt, null);
        Map<String, Object> headers = new LinkedHashMap<>(parsedJwt.getHeader().toJSONObject());
        Map<String, Object> claims = this.claimSetConverter.convert(jwtClaimsSet.getClaims());
        // @formatter:off
        return Jwt.withTokenValue(token).headers((h) -> h.putAll(headers)).claims((c) -> c.putAll(claims)).build();
    // @formatter:on
    } catch (RemoteKeySourceException ex) {
        this.logger.trace("Failed to retrieve JWK set", ex);
        if (ex.getCause() instanceof ParseException) {
            throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed Jwk set"), ex);
        }
        throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
    } catch (JOSEException ex) {
        this.logger.trace("Failed to process JWT", ex);
        throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
    } catch (Exception ex) {
        this.logger.trace("Failed to process JWT", ex);
        if (ex.getCause() instanceof ParseException) {
            throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed payload"), ex);
        }
        throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
    }
}
Also used : Arrays(java.util.Arrays) URL(java.net.URL) JOSEException(com.nimbusds.jose.JOSEException) JWKSet(com.nimbusds.jose.jwk.JWKSet) OAuth2TokenValidator(org.springframework.security.oauth2.core.OAuth2TokenValidator) JWTParser(com.nimbusds.jwt.JWTParser) MacAlgorithm(org.springframework.security.oauth2.jose.jws.MacAlgorithm) JWKSetCache(com.nimbusds.jose.jwk.source.JWKSetCache) PlainJWT(com.nimbusds.jwt.PlainJWT) RSAPublicKey(java.security.interfaces.RSAPublicKey) Map(java.util.Map) JWT(com.nimbusds.jwt.JWT) ParseException(java.text.ParseException) RestTemplate(org.springframework.web.client.RestTemplate) JWKSource(com.nimbusds.jose.jwk.source.JWKSource) HttpHeaders(org.springframework.http.HttpHeaders) Collection(java.util.Collection) MediaType(org.springframework.http.MediaType) Set(java.util.Set) JWSAlgorithm(com.nimbusds.jose.JWSAlgorithm) JWSVerificationKeySelector(com.nimbusds.jose.proc.JWSVerificationKeySelector) SecretKey(javax.crypto.SecretKey) LogFactory(org.apache.commons.logging.LogFactory) OAuth2TokenValidatorResult(org.springframework.security.oauth2.core.OAuth2TokenValidatorResult) SecurityContext(com.nimbusds.jose.proc.SecurityContext) Resource(com.nimbusds.jose.util.Resource) JWSKeySelector(com.nimbusds.jose.proc.JWSKeySelector) Cache(org.springframework.cache.Cache) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) JWTProcessor(com.nimbusds.jwt.proc.JWTProcessor) RemoteJWKSet(com.nimbusds.jose.jwk.source.RemoteJWKSet) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) RemoteKeySourceException(com.nimbusds.jose.RemoteKeySourceException) DefaultJWTProcessor(com.nimbusds.jwt.proc.DefaultJWTProcessor) Converter(org.springframework.core.convert.converter.Converter) RequestEntity(org.springframework.http.RequestEntity) ConfigurableJWTProcessor(com.nimbusds.jwt.proc.ConfigurableJWTProcessor) MalformedURLException(java.net.MalformedURLException) HttpMethod(org.springframework.http.HttpMethod) IOException(java.io.IOException) RestOperations(org.springframework.web.client.RestOperations) SingleKeyJWSKeySelector(com.nimbusds.jose.proc.SingleKeyJWSKeySelector) ResourceRetriever(com.nimbusds.jose.util.ResourceRetriever) Consumer(java.util.function.Consumer) SignatureAlgorithm(org.springframework.security.oauth2.jose.jws.SignatureAlgorithm) OAuth2Error(org.springframework.security.oauth2.core.OAuth2Error) Log(org.apache.commons.logging.Log) ResponseEntity(org.springframework.http.ResponseEntity) Collections(java.util.Collections) Assert(org.springframework.util.Assert) StringUtils(org.springframework.util.StringUtils) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) RemoteKeySourceException(com.nimbusds.jose.RemoteKeySourceException) ParseException(java.text.ParseException) JOSEException(com.nimbusds.jose.JOSEException) JOSEException(com.nimbusds.jose.JOSEException) ParseException(java.text.ParseException) RemoteKeySourceException(com.nimbusds.jose.RemoteKeySourceException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

JWT (com.nimbusds.jwt.JWT)28 SignedJWT (com.nimbusds.jwt.SignedJWT)17 PlainJWT (com.nimbusds.jwt.PlainJWT)16 Test (org.junit.Test)14 AccessToken (com.nimbusds.oauth2.sdk.token.AccessToken)9 BearerAccessToken (com.nimbusds.oauth2.sdk.token.BearerAccessToken)9 WebContext (org.pac4j.core.context.WebContext)7 TechnicalException (org.pac4j.core.exception.TechnicalException)6 JWTClaimsSet (com.nimbusds.jwt.JWTClaimsSet)5 JOSEException (com.nimbusds.jose.JOSEException)4 ParseException (com.nimbusds.oauth2.sdk.ParseException)4 IOException (java.io.IOException)4 ParseException (java.text.ParseException)4 AuthorizationCode (com.nimbusds.oauth2.sdk.AuthorizationCode)3 HTTPRequest (com.nimbusds.oauth2.sdk.http.HTTPRequest)3 URI (java.net.URI)3 Date (java.util.Date)3 JWSAlgorithm (com.nimbusds.jose.JWSAlgorithm)2 BadJOSEException (com.nimbusds.jose.proc.BadJOSEException)2 Resource (com.nimbusds.jose.util.Resource)2