Search in sources :

Example 21 with Tokens

use of com.nimbusds.oauth2.sdk.token.Tokens in project di-authentication-api by alphagov.

the class DocAppCallbackHandlerTest method shouldRedirectToFrontendCallbackForSuccessfulResponse.

@Test
void shouldRedirectToFrontendCallbackForSuccessfulResponse() throws URISyntaxException {
    usingValidSession();
    usingValidClientSession();
    var successfulTokenResponse = new AccessTokenResponse(new Tokens(new BearerAccessToken(), null));
    var tokenRequest = mock(TokenRequest.class);
    Map<String, String> responseHeaders = new HashMap<>();
    responseHeaders.put("code", AUTH_CODE.getValue());
    responseHeaders.put("state", STATE.getValue());
    when(responseService.validateResponse(responseHeaders, SESSION_ID)).thenReturn(Optional.empty());
    when(tokenService.constructTokenRequest(AUTH_CODE.getValue())).thenReturn(tokenRequest);
    when(tokenService.sendTokenRequest(tokenRequest)).thenReturn(successfulTokenResponse);
    when(tokenService.sendCriDataRequest(successfulTokenResponse.getTokens().getAccessToken())).thenReturn("a-verifiable-credential");
    var event = new APIGatewayProxyRequestEvent();
    event.setQueryStringParameters(responseHeaders);
    event.setHeaders(Map.of(COOKIE, buildCookieString()));
    var response = makeHandlerRequest(event);
    assertThat(response, hasStatus(302));
    var expectedRedirectURI = new URIBuilder(LOGIN_URL).setPath("doc-checking-app-callback").build();
    assertThat(response.getHeaders().get("Location"), equalTo(expectedRedirectURI.toString()));
    verify(auditService).submitAuditEvent(DocAppAuditableEvent.DOC_APP_AUTHORISATION_RESPONSE_RECEIVED, REQUEST_ID, SESSION_ID, CLIENT_ID.getValue(), PAIRWISE_SUBJECT_ID.getValue(), AuditService.UNKNOWN, AuditService.UNKNOWN, AuditService.UNKNOWN, AuditService.UNKNOWN);
    verify(auditService).submitAuditEvent(DocAppAuditableEvent.DOC_APP_SUCCESSFUL_TOKEN_RESPONSE_RECEIVED, REQUEST_ID, SESSION_ID, CLIENT_ID.getValue(), PAIRWISE_SUBJECT_ID.getValue(), AuditService.UNKNOWN, AuditService.UNKNOWN, AuditService.UNKNOWN, AuditService.UNKNOWN);
    verify(auditService).submitAuditEvent(DocAppAuditableEvent.DOC_APP_SUCCESSFUL_CREDENTIAL_RESPONSE_RECEIVED, REQUEST_ID, SESSION_ID, CLIENT_ID.getValue(), PAIRWISE_SUBJECT_ID.getValue(), AuditService.UNKNOWN, AuditService.UNKNOWN, AuditService.UNKNOWN, AuditService.UNKNOWN);
    verifyNoMoreInteractions(auditService);
    verify(dynamoDocAppService).addDocAppCredential(PAIRWISE_SUBJECT_ID.getValue(), "a-verifiable-credential");
}
Also used : APIGatewayProxyRequestEvent(com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent) HashMap(java.util.HashMap) BearerAccessToken(com.nimbusds.oauth2.sdk.token.BearerAccessToken) Matchers.containsString(org.hamcrest.Matchers.containsString) AccessTokenResponse(com.nimbusds.oauth2.sdk.AccessTokenResponse) Tokens(com.nimbusds.oauth2.sdk.token.Tokens) URIBuilder(org.apache.http.client.utils.URIBuilder) Test(org.junit.jupiter.api.Test)

Example 22 with Tokens

use of com.nimbusds.oauth2.sdk.token.Tokens in project di-authentication-api by alphagov.

the class TokenHandler method tokenRequestHandler.

public APIGatewayProxyResponseEvent tokenRequestHandler(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());
        addAnnotation("grant_type", requestBody.get("grant_type"));
        String clientID;
        ClientRegistry client;
        try {
            clientID = tokenService.getClientIDFromPrivateKeyJWT(input.getBody()).orElseThrow();
            attachLogFieldToLogs(CLIENT_ID, clientID);
            addAnnotation("client_id", clientID);
            client = clientService.getClient(clientID).orElseThrow();
        } catch (NoSuchElementException e) {
            LOG.warn("Invalid client or client not found in Client Registry");
            return generateApiGatewayProxyResponse(400, OAuth2Error.INVALID_CLIENT.toJSONObject().toJSONString());
        }
        String baseUrl = configurationService.getOidcApiBaseURL().orElseThrow(() -> {
            LOG.error("Application was not configured with baseURL");
            return new RuntimeException("Application was not configured with baseURL");
        });
        String tokenUrl = buildURI(baseUrl, TOKEN_PATH).toString();
        Optional<ErrorObject> invalidPrivateKeyJwtError = segmentedFunctionCall("validatePrivateKeyJWT", () -> 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 segmentedFunctionCall("processRefreshTokenRequest", () -> processRefreshTokenRequest(requestBody, client.getScopes(), new RefreshToken(requestBody.get("refresh_token")), clientID));
        }
        AuthCodeExchangeData authCodeExchangeData;
        try {
            authCodeExchangeData = segmentedFunctionCall("authorisationCodeService", () -> 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());
        }
        updateAttachedLogFieldToLogs(CLIENT_SESSION_ID, authCodeExchangeData.getClientSessionId());
        ClientSession clientSession = authCodeExchangeData.getClientSession();
        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));
        }
        var authRequestRedirectURI = isDocCheckingAppUserWithSubjectId(clientSession) ? getRequestObjectClaim(authRequest, "redirect_uri", String.class) : authRequest.getRedirectionURI().toString();
        if (!authRequestRedirectURI.equals(requestBody.get("redirect_uri"))) {
            LOG.warn("Redirect URI for auth request ({}) does not match redirect URI for request body ({})", authRequestRedirectURI, requestBody.get("redirect_uri"));
            return generateApiGatewayProxyResponse(400, OAuth2Error.INVALID_GRANT.toJSONObject().toJSONString());
        }
        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 isConsentRequired = client.isConsentRequired() && !clientSession.getEffectiveVectorOfTrust().containsLevelOfConfidence();
        final OIDCClaimsRequest finalClaimsRequest = claimsRequest;
        OIDCTokenResponse tokenResponse;
        if (isDocCheckingAppUserWithSubjectId(clientSession)) {
            LOG.info("Doc Checking App User with SubjectId: true");
            Scope scope = new Scope(getRequestObjectScopeClaim(authRequest));
            tokenResponse = segmentedFunctionCall("generateTokenResponse", () -> tokenService.generateTokenResponse(clientID, clientSession.getDocAppSubjectId(), scope, additionalTokenClaims, clientSession.getDocAppSubjectId(), vot, null, false, finalClaimsRequest, true));
        } else {
            UserProfile userProfile = dynamoService.getUserProfileByEmail(authCodeExchangeData.getEmail());
            Subject subject = ClientSubjectHelper.getSubject(userProfile, client, dynamoService);
            tokenResponse = segmentedFunctionCall("generateTokenResponse", () -> tokenService.generateTokenResponse(clientID, new Subject(userProfile.getSubjectID()), authRequest.getScope(), additionalTokenClaims, subject, vot, userProfile.getClientConsent(), isConsentRequired, finalClaimsRequest, false));
        }
        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) OIDCTokenResponse(com.nimbusds.openid.connect.sdk.OIDCTokenResponse) 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) Scope(com.nimbusds.oauth2.sdk.Scope) 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 23 with Tokens

use of com.nimbusds.oauth2.sdk.token.Tokens in project nifi by apache.

the class StandardOidcIdentityProvider method exchangeAuthorizationCode.

@Override
public String exchangeAuthorizationCode(final AuthorizationGrant authorizationGrant) throws IOException {
    if (!isOidcEnabled()) {
        throw new IllegalStateException(OPEN_ID_CONNECT_SUPPORT_IS_NOT_CONFIGURED);
    }
    final ClientAuthentication clientAuthentication;
    if (oidcProviderMetadata.getTokenEndpointAuthMethods().contains(ClientAuthenticationMethod.CLIENT_SECRET_POST)) {
        clientAuthentication = new ClientSecretPost(clientId, clientSecret);
    } else {
        clientAuthentication = new ClientSecretBasic(clientId, clientSecret);
    }
    try {
        // build the token request
        final TokenRequest request = new TokenRequest(oidcProviderMetadata.getTokenEndpointURI(), clientAuthentication, authorizationGrant, getScope());
        final HTTPRequest tokenHttpRequest = request.toHTTPRequest();
        tokenHttpRequest.setConnectTimeout(oidcConnectTimeout);
        tokenHttpRequest.setReadTimeout(oidcReadTimeout);
        // get the token response
        final TokenResponse response = OIDCTokenResponseParser.parse(tokenHttpRequest.send());
        if (response.indicatesSuccess()) {
            final OIDCTokenResponse oidcTokenResponse = (OIDCTokenResponse) response;
            final OIDCTokens oidcTokens = oidcTokenResponse.getOIDCTokens();
            final JWT oidcJwt = oidcTokens.getIDToken();
            // validate the token - no nonce required for authorization code flow
            final IDTokenClaimsSet claimsSet = tokenValidator.validate(oidcJwt, null);
            // attempt to extract the email from the id token if possible
            String email = claimsSet.getStringClaim(EMAIL_CLAIM_NAME);
            if (StringUtils.isBlank(email)) {
                // extract the bearer access token
                final BearerAccessToken bearerAccessToken = oidcTokens.getBearerAccessToken();
                if (bearerAccessToken == null) {
                    throw new IllegalStateException("No access token found in the ID tokens");
                }
                // invoke the UserInfo endpoint
                email = lookupEmail(bearerAccessToken);
            }
            // extract expiration details from the claims set
            final Calendar now = Calendar.getInstance();
            final Date expiration = claimsSet.getExpirationTime();
            final long expiresIn = expiration.getTime() - now.getTimeInMillis();
            // convert into a nifi jwt for retrieval later
            final LoginAuthenticationToken loginToken = new LoginAuthenticationToken(email, email, expiresIn, claimsSet.getIssuer().getValue());
            return jwtService.generateSignedToken(loginToken);
        } else {
            final TokenErrorResponse errorResponse = (TokenErrorResponse) response;
            throw new RuntimeException("An error occurred while invoking the Token endpoint: " + errorResponse.getErrorObject().getDescription());
        }
    } catch (final ParseException | JOSEException | BadJOSEException e) {
        throw new RuntimeException("Unable to parse the response from the Token request: " + e.getMessage());
    }
}
Also used : HTTPRequest(com.nimbusds.oauth2.sdk.http.HTTPRequest) JWT(com.nimbusds.jwt.JWT) OIDCTokenResponse(com.nimbusds.openid.connect.sdk.OIDCTokenResponse) Calendar(java.util.Calendar) IDTokenClaimsSet(com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet) ClientSecretBasic(com.nimbusds.oauth2.sdk.auth.ClientSecretBasic) Date(java.util.Date) TokenErrorResponse(com.nimbusds.oauth2.sdk.TokenErrorResponse) ClientSecretPost(com.nimbusds.oauth2.sdk.auth.ClientSecretPost) OIDCTokenResponse(com.nimbusds.openid.connect.sdk.OIDCTokenResponse) TokenResponse(com.nimbusds.oauth2.sdk.TokenResponse) BadJOSEException(com.nimbusds.jose.proc.BadJOSEException) OIDCTokens(com.nimbusds.openid.connect.sdk.token.OIDCTokens) LoginAuthenticationToken(org.apache.nifi.web.security.token.LoginAuthenticationToken) TokenRequest(com.nimbusds.oauth2.sdk.TokenRequest) BearerAccessToken(com.nimbusds.oauth2.sdk.token.BearerAccessToken) ParseException(com.nimbusds.oauth2.sdk.ParseException) ClientAuthentication(com.nimbusds.oauth2.sdk.auth.ClientAuthentication) JOSEException(com.nimbusds.jose.JOSEException) BadJOSEException(com.nimbusds.jose.proc.BadJOSEException)

Example 24 with Tokens

use of com.nimbusds.oauth2.sdk.token.Tokens in project timbuctoo by HuygensING.

the class OpenIdClient method getUserTokens.

public Optional<Tokens> getUserTokens(String code) throws IOException, ParseException {
    final ClientAuthentication basicAuth = new ClientSecretBasic(new ClientID(clientId), new Secret(clientSecret));
    final URI redirectUri = fromUri(redirectUrl).build();
    final AuthorizationCodeGrant authzGrant = new AuthorizationCodeGrant(new AuthorizationCode(code), redirectUri);
    final TokenRequest tokenRequest = new TokenRequest(getTokenUrl(discoveryUrl), basicAuth, authzGrant);
    final TokenResponse response = OIDCTokenResponseParser.parse(tokenRequest.toHTTPRequest().send());
    if (response.indicatesSuccess()) {
        final Tokens tokens = response.toSuccessResponse().getTokens();
        // TODO check if the id is not fake
        return Optional.of(tokens);
    } else {
        LOG.error("Could not retrieve client token: {}", response.toErrorResponse().getErrorObject());
        return Optional.empty();
    }
}
Also used : Secret(com.nimbusds.oauth2.sdk.auth.Secret) AuthorizationCode(com.nimbusds.oauth2.sdk.AuthorizationCode) TokenResponse(com.nimbusds.oauth2.sdk.TokenResponse) AuthorizationCodeGrant(com.nimbusds.oauth2.sdk.AuthorizationCodeGrant) TokenRequest(com.nimbusds.oauth2.sdk.TokenRequest) ClientID(com.nimbusds.oauth2.sdk.id.ClientID) ClientAuthentication(com.nimbusds.oauth2.sdk.auth.ClientAuthentication) URI(java.net.URI) ClientSecretBasic(com.nimbusds.oauth2.sdk.auth.ClientSecretBasic) Tokens(com.nimbusds.oauth2.sdk.token.Tokens)

Example 25 with Tokens

use of com.nimbusds.oauth2.sdk.token.Tokens in project ddf by codice.

the class OAuthSecurityImpl method getValidToken.

/**
 * Attempts to get an unexpired access token from the token storage or by making a request to the
 * OAuth provider.
 *
 * @param id The ID used when retrieving tokens from the token storage
 * @param sourceId The ID of the source using OAuth needed to get the correct tokens
 * @param clientId The client ID registered with the OAuth provider
 * @param clientSecret The client secret registered with the OAuth provider
 * @param discoveryUrl The discovery URL of the OAuth provider
 * @param grantType The grant type used if a request is sent to get a new token
 * @param queryParameters Parameters used if a request is sent to get a new token
 * @return an access token or null if all means of getting one fail
 */
private String getValidToken(String id, String sourceId, String clientId, String clientSecret, String discoveryUrl, String grantType, Map<String, String> queryParameters) {
    TokenEntry tokenEntry = tokenStorage.read(id, sourceId);
    if (tokenEntry != null && discoveryUrl.equalsIgnoreCase(tokenEntry.getDiscoveryUrl()) && !isExpired(tokenEntry.getAccessToken())) {
        return tokenEntry.getAccessToken();
    }
    OIDCProviderMetadata metadata;
    try {
        metadata = OIDCProviderMetadata.parse(resourceRetriever.retrieveResource(new URL(discoveryUrl)).getContent());
    } catch (IOException | ParseException e) {
        LOGGER.error("Unable to retrieve OAuth provider's metadata.", e);
        return null;
    }
    if (tokenEntry != null && discoveryUrl.equalsIgnoreCase(tokenEntry.getDiscoveryUrl()) && isExpired(tokenEntry.getAccessToken()) && !isExpired(tokenEntry.getRefreshToken())) {
        // refresh token
        return refreshToken(id, sourceId, clientId, clientSecret, discoveryUrl, tokenEntry.getRefreshToken(), metadata);
    }
    // Make a call to get a token
    String encodedClientIdSecret = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(UTF_8));
    return getNewAccessToken(id, sourceId, encodedClientIdSecret, discoveryUrl, grantType, queryParameters, metadata);
}
Also used : TokenEntry(org.codice.ddf.security.token.storage.api.TokenInformation.TokenEntry) OIDCProviderMetadata(com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata) IOException(java.io.IOException) ParseException(com.nimbusds.oauth2.sdk.ParseException) URL(java.net.URL)

Aggregations

URI (java.net.URI)18 OIDCTokens (com.nimbusds.openid.connect.sdk.token.OIDCTokens)17 ClientSecretBasic (com.nimbusds.oauth2.sdk.auth.ClientSecretBasic)15 ClientID (com.nimbusds.oauth2.sdk.id.ClientID)15 OIDCTokenResponse (com.nimbusds.openid.connect.sdk.OIDCTokenResponse)15 TokenResponse (com.nimbusds.oauth2.sdk.TokenResponse)14 TokenRequest (com.nimbusds.oauth2.sdk.TokenRequest)13 BearerAccessToken (com.nimbusds.oauth2.sdk.token.BearerAccessToken)13 Secret (com.nimbusds.oauth2.sdk.auth.Secret)12 HTTPResponse (com.nimbusds.oauth2.sdk.http.HTTPResponse)12 Tokens (com.nimbusds.oauth2.sdk.token.Tokens)11 TokenErrorResponse (com.nimbusds.oauth2.sdk.TokenErrorResponse)10 ClientAuthentication (com.nimbusds.oauth2.sdk.auth.ClientAuthentication)10 AccessToken (com.nimbusds.oauth2.sdk.token.AccessToken)10 IOException (java.io.IOException)10 AccessTokenResponse (com.nimbusds.oauth2.sdk.AccessTokenResponse)8 Scope (com.nimbusds.oauth2.sdk.Scope)8 RefreshToken (com.nimbusds.oauth2.sdk.token.RefreshToken)8 HashMap (java.util.HashMap)8 Test (org.testng.annotations.Test)8