Search in sources :

Example 6 with OIDCClaimsRequest

use of com.nimbusds.openid.connect.sdk.OIDCClaimsRequest in project di-authentication-api by alphagov.

the class IPVAuthorisationHandlerTest method withAuthenticationRequest.

private AuthenticationRequest withAuthenticationRequest(String clientId) {
    Scope scope = new Scope();
    scope.add(OIDCScopeValue.OPENID);
    var oidcClaimsRequest = new OIDCClaimsRequest().withUserInfoClaimsRequest(claimsSetRequest);
    return new AuthenticationRequest.Builder(new ResponseType(ResponseType.Value.CODE), scope, new ClientID(clientId), REDIRECT_URI).state(new State()).nonce(new Nonce()).claims(oidcClaimsRequest).build();
}
Also used : Nonce(com.nimbusds.openid.connect.sdk.Nonce) OIDCClaimsRequest(com.nimbusds.openid.connect.sdk.OIDCClaimsRequest) Scope(com.nimbusds.oauth2.sdk.Scope) State(com.nimbusds.oauth2.sdk.id.State) ClientID(com.nimbusds.oauth2.sdk.id.ClientID) ResponseType(com.nimbusds.oauth2.sdk.ResponseType)

Example 7 with OIDCClaimsRequest

use of com.nimbusds.openid.connect.sdk.OIDCClaimsRequest in project di-authentication-api by alphagov.

the class TokenHandler method handleRequest.

@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
    return isWarming(input).orElseGet(() -> {
        LOG.info("Token request received");
        Optional<ErrorObject> invalidRequestParamError = tokenService.validateTokenRequestParams(input.getBody());
        if (invalidRequestParamError.isPresent()) {
            LOG.warn("Invalid Token Request. ErrorCode: {}. ErrorDescription: {}", invalidRequestParamError.get().getCode(), invalidRequestParamError.get().getDescription());
            return generateApiGatewayProxyResponse(400, invalidRequestParamError.get().toJSONObject().toJSONString());
        }
        Map<String, String> requestBody = parseRequestBody(input.getBody());
        String clientID = requestBody.get("client_id");
        ClientRegistry client;
        try {
            client = clientService.getClient(clientID).orElseThrow();
        } catch (NoSuchElementException e) {
            LOG.warn("Client not found in Client Registry with Client ID {}", clientID);
            return generateApiGatewayProxyResponse(400, OAuth2Error.INVALID_CLIENT.toJSONObject().toJSONString());
        }
        String baseUrl = configurationService.getBaseURL().orElseThrow(() -> {
            LOG.error("Application was not configured with baseURL");
            // exceptions
            return new RuntimeException("Application was not configured with baseURL");
        });
        String tokenUrl = buildURI(baseUrl, TOKEN_PATH).toString();
        Optional<ErrorObject> invalidPrivateKeyJwtError = tokenService.validatePrivateKeyJWT(input.getBody(), client.getPublicKey(), tokenUrl, clientID);
        if (invalidPrivateKeyJwtError.isPresent()) {
            LOG.warn("Private Key JWT is not valid for Client ID: {}", clientID);
            return generateApiGatewayProxyResponse(400, invalidPrivateKeyJwtError.get().toJSONObject().toJSONString());
        }
        if (requestBody.get("grant_type").equals(GrantType.REFRESH_TOKEN.getValue())) {
            LOG.info("Processing refresh token request");
            return processRefreshTokenRequest(requestBody, client.getScopes(), new RefreshToken(requestBody.get("refresh_token")));
        }
        AuthCodeExchangeData authCodeExchangeData;
        try {
            authCodeExchangeData = authorisationCodeService.getExchangeDataForCode(requestBody.get("code")).orElseThrow();
        } catch (NoSuchElementException e) {
            LOG.warn("Could not retrieve client session ID from code", e);
            return generateApiGatewayProxyResponse(400, OAuth2Error.INVALID_GRANT.toJSONObject().toJSONString());
        }
        ClientSession clientSession = clientSessionService.getClientSession(authCodeExchangeData.getClientSessionId());
        AuthenticationRequest authRequest;
        try {
            authRequest = AuthenticationRequest.parse(clientSession.getAuthRequestParams());
        } catch (ParseException e) {
            LOG.warn("Could not parse authentication request from client session", e);
            throw new RuntimeException(format("Unable to parse Auth Request\n Auth Request Params: %s \n Exception: %s", clientSession.getAuthRequestParams(), e));
        }
        if (!authRequest.getRedirectionURI().toString().equals(requestBody.get("redirect_uri"))) {
            LOG.warn("Redirect URI for auth request ({}) does not match redirect URI for request body ({})", authRequest.getRedirectionURI(), requestBody.get("redirect_uri"));
            return generateApiGatewayProxyResponse(400, OAuth2Error.INVALID_GRANT.toJSONObject().toJSONString());
        }
        UserProfile userProfile = dynamoService.getUserProfileByEmail(authCodeExchangeData.getEmail());
        Subject publicSubject = ClientSubjectHelper.getSubject(userProfile, client, dynamoService);
        Map<String, Object> additionalTokenClaims = new HashMap<>();
        if (authRequest.getNonce() != null) {
            additionalTokenClaims.put("nonce", authRequest.getNonce());
        }
        String vot = clientSession.getEffectiveVectorOfTrust().retrieveVectorOfTrustForToken();
        OIDCClaimsRequest claimsRequest = null;
        if (Objects.nonNull(clientSession.getEffectiveVectorOfTrust().getLevelOfConfidence()) && Objects.nonNull(authRequest.getOIDCClaims())) {
            claimsRequest = authRequest.getOIDCClaims();
        }
        var tokenResponse = tokenService.generateTokenResponse(clientID, new Subject(userProfile.getSubjectID()), authRequest.getScope(), additionalTokenClaims, publicSubject, vot, userProfile.getClientConsent(), client.isConsentRequired(), claimsRequest);
        clientSessionService.saveClientSession(authCodeExchangeData.getClientSessionId(), clientSession.setIdTokenHint(tokenResponse.getOIDCTokens().getIDToken().serialize()));
        LOG.info("Successfully generated tokens");
        return generateApiGatewayProxyResponse(200, tokenResponse.toJSONObject().toJSONString());
    });
}
Also used : UserProfile(uk.gov.di.authentication.shared.entity.UserProfile) HashMap(java.util.HashMap) ErrorObject(com.nimbusds.oauth2.sdk.ErrorObject) Subject(com.nimbusds.oauth2.sdk.id.Subject) AuthCodeExchangeData(uk.gov.di.authentication.shared.entity.AuthCodeExchangeData) OIDCClaimsRequest(com.nimbusds.openid.connect.sdk.OIDCClaimsRequest) RefreshToken(com.nimbusds.oauth2.sdk.token.RefreshToken) ClientSession(uk.gov.di.authentication.shared.entity.ClientSession) ClientRegistry(uk.gov.di.authentication.shared.entity.ClientRegistry) ErrorObject(com.nimbusds.oauth2.sdk.ErrorObject) ParseException(com.nimbusds.oauth2.sdk.ParseException) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) NoSuchElementException(java.util.NoSuchElementException)

Example 8 with OIDCClaimsRequest

use of com.nimbusds.openid.connect.sdk.OIDCClaimsRequest in project di-authentication-api by alphagov.

the class AuthorizationServiceTest method shouldReturnErrorWhenValidatingAuthRequestWhichContainsInvalidClaims.

@Test
void shouldReturnErrorWhenValidatingAuthRequestWhichContainsInvalidClaims() {
    ResponseType responseType = new ResponseType(ResponseType.Value.CODE);
    Scope scope = new Scope();
    scope.add(OIDCScopeValue.OPENID);
    when(dynamoClientService.getClient(CLIENT_ID.toString())).thenReturn(Optional.of(generateClientRegistry(REDIRECT_URI.toString(), CLIENT_ID.toString())));
    var claimsSetRequest = new ClaimsSetRequest().add("nickname").add("birthdate");
    var oidcClaimsRequest = new OIDCClaimsRequest().withUserInfoClaimsRequest(claimsSetRequest);
    AuthenticationRequest authRequest = generateAuthRequest(REDIRECT_URI.toString(), responseType, scope, jsonArrayOf("Cl.Cm", "Cl"), Optional.of(oidcClaimsRequest));
    Optional<ErrorObject> errorObject = authorizationService.validateAuthRequest(authRequest);
    assertThat(errorObject, equalTo(Optional.of(new ErrorObject(OAuth2Error.INVALID_REQUEST_CODE, "Request contains invalid claims"))));
}
Also used : ClaimsSetRequest(com.nimbusds.openid.connect.sdk.claims.ClaimsSetRequest) OIDCClaimsRequest(com.nimbusds.openid.connect.sdk.OIDCClaimsRequest) Scope(com.nimbusds.oauth2.sdk.Scope) ErrorObject(com.nimbusds.oauth2.sdk.ErrorObject) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) ResponseType(com.nimbusds.oauth2.sdk.ResponseType) Test(org.junit.jupiter.api.Test)

Example 9 with OIDCClaimsRequest

use of com.nimbusds.openid.connect.sdk.OIDCClaimsRequest in project di-authentication-api by alphagov.

the class AuthorizationServiceTest method shouldSuccessfullyValidateAuthRequestWhenValidClaimsArePresent.

@Test
void shouldSuccessfullyValidateAuthRequestWhenValidClaimsArePresent() {
    ResponseType responseType = new ResponseType(ResponseType.Value.CODE);
    Scope scope = new Scope();
    scope.add(OIDCScopeValue.OPENID);
    when(dynamoClientService.getClient(CLIENT_ID.toString())).thenReturn(Optional.of(generateClientRegistry(REDIRECT_URI.toString(), CLIENT_ID.toString())));
    var claimsSetRequest = new ClaimsSetRequest().add("name").add("birthdate");
    var oidcClaimsRequest = new OIDCClaimsRequest().withUserInfoClaimsRequest(claimsSetRequest);
    AuthenticationRequest authRequest = generateAuthRequest(REDIRECT_URI.toString(), responseType, scope, jsonArrayOf("Cl.Cm", "Cl"), Optional.of(oidcClaimsRequest));
    Optional<ErrorObject> errorObject = authorizationService.validateAuthRequest(authRequest);
    assertThat(errorObject, equalTo(Optional.empty()));
}
Also used : ClaimsSetRequest(com.nimbusds.openid.connect.sdk.claims.ClaimsSetRequest) OIDCClaimsRequest(com.nimbusds.openid.connect.sdk.OIDCClaimsRequest) Scope(com.nimbusds.oauth2.sdk.Scope) ErrorObject(com.nimbusds.oauth2.sdk.ErrorObject) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) ResponseType(com.nimbusds.oauth2.sdk.ResponseType) Test(org.junit.jupiter.api.Test)

Example 10 with OIDCClaimsRequest

use of com.nimbusds.openid.connect.sdk.OIDCClaimsRequest in project di-authentication-api by alphagov.

the class TokenServiceTest method shouldOnlyIncludeIdentityClaimsInAccessTokenWhenRequested.

@Test
void shouldOnlyIncludeIdentityClaimsInAccessTokenWhenRequested() throws ParseException, JOSEException, Json.JsonException, com.nimbusds.oauth2.sdk.ParseException {
    var claimsSetRequest = new ClaimsSetRequest().add("nickname").add("birthdate");
    var oidcClaimsRequest = new OIDCClaimsRequest().withUserInfoClaimsRequest(claimsSetRequest);
    when(configurationService.getTokenSigningKeyAlias()).thenReturn(KEY_ID);
    createSignedIdToken();
    createSignedAccessToken();
    Map<String, Object> additionalTokenClaims = new HashMap<>();
    additionalTokenClaims.put("nonce", nonce);
    Set<String> claimsForListOfScopes = ValidScopes.getClaimsForListOfScopes(SCOPES_OFFLINE_ACCESS.toStringList());
    OIDCTokenResponse tokenResponse = tokenService.generateTokenResponse(CLIENT_ID, INTERNAL_SUBJECT, SCOPES_OFFLINE_ACCESS, additionalTokenClaims, PUBLIC_SUBJECT, VOT, Collections.singletonList(new ClientConsent(CLIENT_ID, claimsForListOfScopes, LocalDateTime.now(ZoneId.of("UTC")).toString())), false, oidcClaimsRequest, false);
    assertSuccessfullTokenResponse(tokenResponse);
    assertNotNull(tokenResponse.getOIDCTokens().getRefreshToken());
    assertNull(SignedJWT.parse(tokenResponse.getOIDCTokens().getRefreshToken().getValue()).getJWTClaimsSet().getClaim("claims"));
    JSONArray jsonarray = JSONArrayUtils.parse(SignedJWT.parse(tokenResponse.getOIDCTokens().getAccessToken().getValue()).getJWTClaimsSet().getClaim("claims").toString());
    assertTrue(jsonarray.contains("nickname"));
    assertTrue(jsonarray.contains("birthdate"));
    RefreshTokenStore refreshTokenStore = new RefreshTokenStore(tokenResponse.getOIDCTokens().getRefreshToken().getValue(), INTERNAL_SUBJECT.getValue());
    ArgumentCaptor<String> redisKey = ArgumentCaptor.forClass(String.class);
    verify(redisConnectionService).saveWithExpiry(redisKey.capture(), eq(objectMapper.writeValueAsString(refreshTokenStore)), eq(300L));
    var refreshToken = SignedJWT.parse(tokenResponse.getOIDCTokens().getRefreshToken().getValue());
    var jti = refreshToken.getJWTClaimsSet().getJWTID();
    assertThat(redisKey.getValue(), startsWith(REFRESH_TOKEN_PREFIX));
    assertThat(redisKey.getValue().split(":")[1], equalTo(jti));
}
Also used : ClaimsSetRequest(com.nimbusds.openid.connect.sdk.claims.ClaimsSetRequest) RefreshTokenStore(uk.gov.di.authentication.shared.entity.RefreshTokenStore) HashMap(java.util.HashMap) OIDCTokenResponse(com.nimbusds.openid.connect.sdk.OIDCTokenResponse) JSONArray(net.minidev.json.JSONArray) ClientConsent(uk.gov.di.authentication.shared.entity.ClientConsent) OIDCClaimsRequest(com.nimbusds.openid.connect.sdk.OIDCClaimsRequest) ErrorObject(com.nimbusds.oauth2.sdk.ErrorObject) Test(org.junit.jupiter.api.Test)

Aggregations

OIDCClaimsRequest (com.nimbusds.openid.connect.sdk.OIDCClaimsRequest)13 ClaimsSetRequest (com.nimbusds.openid.connect.sdk.claims.ClaimsSetRequest)9 Test (org.junit.jupiter.api.Test)9 Scope (com.nimbusds.oauth2.sdk.Scope)8 ErrorObject (com.nimbusds.oauth2.sdk.ErrorObject)6 ResponseType (com.nimbusds.oauth2.sdk.ResponseType)6 AuthenticationRequest (com.nimbusds.openid.connect.sdk.AuthenticationRequest)5 Subject (com.nimbusds.oauth2.sdk.id.Subject)4 BearerAccessToken (com.nimbusds.oauth2.sdk.token.BearerAccessToken)3 HashMap (java.util.HashMap)3 AccessTokenStore (uk.gov.di.authentication.shared.entity.AccessTokenStore)3 ClientRegistry (uk.gov.di.authentication.shared.entity.ClientRegistry)3 ApiGatewayHandlerIntegrationTest (uk.gov.di.authentication.sharedtest.basetest.ApiGatewayHandlerIntegrationTest)3 JWTClaimsSet (com.nimbusds.jwt.JWTClaimsSet)2 ParseException (com.nimbusds.oauth2.sdk.ParseException)2 ClientID (com.nimbusds.oauth2.sdk.id.ClientID)2 State (com.nimbusds.oauth2.sdk.id.State)2 RefreshToken (com.nimbusds.oauth2.sdk.token.RefreshToken)2 Nonce (com.nimbusds.openid.connect.sdk.Nonce)2 OIDCTokenResponse (com.nimbusds.openid.connect.sdk.OIDCTokenResponse)2