Search in sources :

Example 11 with JWTID

use of com.nimbusds.oauth2.sdk.id.JWTID in project di-authentication-api by alphagov.

the class TokenService method generateAndStoreAccessToken.

private AccessToken generateAndStoreAccessToken(String clientId, Subject internalSubject, List<String> scopes, Subject subject, OIDCClaimsRequest claimsRequest) {
    LOG.info("Generating AccessToken");
    Date expiryDate = NowHelper.nowPlus(configService.getAccessTokenExpiry(), ChronoUnit.SECONDS);
    var jwtID = UUID.randomUUID().toString();
    LOG.info("AccessToken being created with JWTID: {}", jwtID);
    JWTClaimsSet.Builder claimSetBuilder = new JWTClaimsSet.Builder().claim("scope", scopes).issuer(configService.getOidcApiBaseURL().get()).expirationTime(expiryDate).issueTime(NowHelper.now()).claim("client_id", clientId).subject(subject.getValue()).jwtID(jwtID);
    if (Objects.nonNull(claimsRequest)) {
        claimSetBuilder.claim("claims", claimsRequest.getUserInfoClaimsRequest().getEntries().stream().map(ClaimsSetRequest.Entry::getClaimName).collect(Collectors.toList()));
    }
    SignedJWT signedJWT = generateSignedJWT(claimSetBuilder.build(), Optional.empty());
    AccessToken accessToken = new BearerAccessToken(signedJWT.serialize());
    try {
        redisConnectionService.saveWithExpiry(ACCESS_TOKEN_PREFIX + clientId + "." + subject.getValue(), objectMapper.writeValueAsString(new AccessTokenStore(accessToken.getValue(), internalSubject.getValue())), configService.getAccessTokenExpiry());
    } catch (JsonException e) {
        LOG.error("Unable to save access token to Redis");
        throw new RuntimeException(e);
    }
    return accessToken;
}
Also used : JsonException(uk.gov.di.authentication.shared.serialization.Json.JsonException) AccessTokenStore(uk.gov.di.authentication.shared.entity.AccessTokenStore) JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) AccessToken(com.nimbusds.oauth2.sdk.token.AccessToken) BearerAccessToken(com.nimbusds.oauth2.sdk.token.BearerAccessToken) SignedJWT(com.nimbusds.jwt.SignedJWT) BearerAccessToken(com.nimbusds.oauth2.sdk.token.BearerAccessToken) Date(java.util.Date)

Example 12 with JWTID

use of com.nimbusds.oauth2.sdk.id.JWTID in project di-authentication-api by alphagov.

the class AccessTokenService method parse.

public AccessTokenInfo parse(String authorizationHeader, boolean identityEnabled) throws AccessTokenException {
    AccessToken accessToken;
    try {
        accessToken = AccessToken.parse(authorizationHeader, AccessTokenType.BEARER);
    } catch (com.nimbusds.oauth2.sdk.ParseException e) {
        LOG.warn("Unable to parse AccessToken");
        throw new AccessTokenException("Unable to parse AccessToken", BearerTokenError.INVALID_TOKEN);
    }
    SignedJWT signedJWT;
    try {
        signedJWT = SignedJWT.parse(accessToken.getValue());
        var currentDateTime = NowHelper.now();
        if (DateUtils.isBefore(signedJWT.getJWTClaimsSet().getExpirationTime(), currentDateTime, 0)) {
            LOG.warn("Access Token has expired. Access Token expires at: {}. CurrentDateTime is: {}", signedJWT.getJWTClaimsSet().getExpirationTime(), currentDateTime);
            throw new AccessTokenException(INVALID_ACCESS_TOKEN, BearerTokenError.INVALID_TOKEN);
        }
        if (!tokenValidationService.validateAccessTokenSignature(accessToken)) {
            LOG.warn("Unable to validate AccessToken signature");
            throw new AccessTokenException("Unable to validate AccessToken signature", BearerTokenError.INVALID_TOKEN);
        }
        var clientID = signedJWT.getJWTClaimsSet().getStringClaim("client_id");
        var client = clientService.getClient(clientID);
        attachLogFieldToLogs(CLIENT_ID, clientID);
        if (client.isEmpty()) {
            LOG.warn("Client not found");
            throw new AccessTokenException("Client not found", BearerTokenError.INVALID_TOKEN);
        }
        var scopes = JSONArrayUtils.parse(signedJWT.getJWTClaimsSet().getClaim("scope").toString()).stream().map(Objects::toString).collect(Collectors.toList());
        if (!areScopesValid(scopes) || !client.get().getScopes().containsAll(scopes)) {
            LOG.warn("Invalid Scopes: {}", scopes);
            throw new AccessTokenException("Invalid Scopes", OAuth2Error.INVALID_SCOPE);
        }
        List<String> identityClaims = null;
        if (identityEnabled) {
            identityClaims = getIdentityClaims(signedJWT.getJWTClaimsSet());
        }
        var subject = signedJWT.getJWTClaimsSet().getSubject();
        var accessTokenStore = getAccessTokenStore(clientID, subject);
        if (accessTokenStore.isEmpty()) {
            LOG.warn("Access Token Store is empty. Access Token expires at: {}. CurrentDateTime is: {}. JWTID in Access Token sent in request: {}", signedJWT.getJWTClaimsSet().getExpirationTime(), currentDateTime, signedJWT.getJWTClaimsSet().getJWTID());
            throw new AccessTokenException(INVALID_ACCESS_TOKEN, BearerTokenError.INVALID_TOKEN);
        }
        if (!accessTokenStore.get().getToken().equals(accessToken.getValue())) {
            LOG.warn("Access Token in Access Token Store is different to Access Token sent in request");
            var storeJwtId = SignedJWT.parse(accessTokenStore.get().getToken()).getJWTClaimsSet().getJWTID();
            LOG.warn("JWTID in AccessTokenStore: {} compared to JWTID in Access Token sent in request: {}", storeJwtId, signedJWT.getJWTClaimsSet().getJWTID());
            throw new AccessTokenException(INVALID_ACCESS_TOKEN, BearerTokenError.INVALID_TOKEN);
        }
        return new AccessTokenInfo(accessTokenStore.get(), subject, scopes, identityClaims);
    } catch (ParseException e) {
        LOG.warn("Unable to parse AccessToken to SignedJWT");
        throw new AccessTokenException("Unable to parse AccessToken to SignedJWT", BearerTokenError.INVALID_TOKEN);
    } catch (com.nimbusds.oauth2.sdk.ParseException e) {
        LOG.warn("Unable to parse ClaimSet in AccessToken");
        throw new AccessTokenException("Unable to parse ClaimSet in AccessToken", BearerTokenError.INVALID_TOKEN);
    }
}
Also used : AccessTokenInfo(uk.gov.di.authentication.oidc.entity.AccessTokenInfo) AccessToken(com.nimbusds.oauth2.sdk.token.AccessToken) AccessTokenException(uk.gov.di.authentication.shared.exceptions.AccessTokenException) SignedJWT(com.nimbusds.jwt.SignedJWT) ParseException(java.text.ParseException)

Example 13 with JWTID

use of com.nimbusds.oauth2.sdk.id.JWTID in project di-authentication-api by alphagov.

the class IPVTokenServiceTest method signJWTWithKMS.

private void signJWTWithKMS() throws JOSEException {
    var ecSigningKey = new ECKeyGenerator(Curve.P_256).keyID(KEY_ID).algorithm(JWSAlgorithm.ES256).generate();
    var claimsSet = new JWTAuthenticationClaimsSet(new ClientID(CLIENT_ID), singletonList(new Audience(buildURI(IPV_URI.toString(), "token"))), NowHelper.nowPlus(5, ChronoUnit.MINUTES), null, NowHelper.now(), new JWTID());
    var ecdsaSigner = new ECDSASigner(ecSigningKey);
    var jwsHeader = new JWSHeader.Builder(JWSAlgorithm.ES256).keyID(ecSigningKey.getKeyID()).build();
    var signedJWT = new SignedJWT(jwsHeader, claimsSet.toJWTClaimsSet());
    unchecked(signedJWT::sign).accept(ecdsaSigner);
    var signResult = new SignResult();
    byte[] idTokenSignatureDer = ECDSA.transcodeSignatureToDER(signedJWT.getSignature().decode());
    signResult.setSignature(ByteBuffer.wrap(idTokenSignatureDer));
    signResult.setKeyId(KEY_ID);
    signResult.setSigningAlgorithm(JWSAlgorithm.ES256.getName());
    when(kmsService.sign(any(SignRequest.class))).thenReturn(signResult);
}
Also used : SignResult(com.amazonaws.services.kms.model.SignResult) SignRequest(com.amazonaws.services.kms.model.SignRequest) Audience(com.nimbusds.oauth2.sdk.id.Audience) ECDSASigner(com.nimbusds.jose.crypto.ECDSASigner) ECKeyGenerator(com.nimbusds.jose.jwk.gen.ECKeyGenerator) ClientID(com.nimbusds.oauth2.sdk.id.ClientID) JWTID(com.nimbusds.oauth2.sdk.id.JWTID) JWTAuthenticationClaimsSet(com.nimbusds.oauth2.sdk.auth.JWTAuthenticationClaimsSet) SignedJWT(com.nimbusds.jwt.SignedJWT)

Aggregations

SignedJWT (com.nimbusds.jwt.SignedJWT)9 JWTClaimsSet (com.nimbusds.jwt.JWTClaimsSet)6 ClientID (com.nimbusds.oauth2.sdk.id.ClientID)5 JWTAuthenticationClaimsSet (com.nimbusds.oauth2.sdk.auth.JWTAuthenticationClaimsSet)4 Audience (com.nimbusds.oauth2.sdk.id.Audience)4 JWTID (com.nimbusds.oauth2.sdk.id.JWTID)4 AccessToken (com.nimbusds.oauth2.sdk.token.AccessToken)4 BearerAccessToken (com.nimbusds.oauth2.sdk.token.BearerAccessToken)4 Date (java.util.Date)4 AccessTokenStore (uk.gov.di.authentication.shared.entity.AccessTokenStore)4 Test (org.junit.jupiter.api.Test)3 ApiGatewayHandlerIntegrationTest (uk.gov.di.authentication.sharedtest.basetest.ApiGatewayHandlerIntegrationTest)3 SignRequest (com.amazonaws.services.kms.model.SignRequest)2 SignResult (com.amazonaws.services.kms.model.SignResult)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 ECDSASigner (com.nimbusds.jose.crypto.ECDSASigner)2 ECKeyGenerator (com.nimbusds.jose.jwk.gen.ECKeyGenerator)2 AuthorizationCode (com.nimbusds.oauth2.sdk.AuthorizationCode)2 AuthorizationCodeGrant (com.nimbusds.oauth2.sdk.AuthorizationCodeGrant)2 TokenRequest (com.nimbusds.oauth2.sdk.TokenRequest)2