Search in sources :

Example 1 with CodeChallengeMethod

use of com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod in project OpenConext-oidcng by OpenConext.

the class AuthorizationEndpoint method createAndSaveAuthorizationCode.

private AuthorizationCode createAndSaveAuthorizationCode(AuthorizationRequest authorizationRequest, OpenIDClient client, User user) {
    URI redirectionURI = authorizationRequest.getRedirectionURI();
    Scope scope = authorizationRequest.getScope();
    List<String> scopes = scope != null ? scope.toStringList() : Collections.emptyList();
    // Optional code challenges for PKCE
    CodeChallenge codeChallenge = authorizationRequest.getCodeChallenge();
    String codeChallengeValue = codeChallenge != null ? codeChallenge.getValue() : null;
    CodeChallengeMethod codeChallengeMethod = authorizationRequest.getCodeChallengeMethod();
    String codeChallengeMethodValue = codeChallengeMethod != null ? codeChallengeMethod.getValue() : (codeChallengeValue != null ? CodeChallengeMethod.getDefault().getValue() : null);
    List<String> idTokenClaims = getClaims(authorizationRequest);
    String code = tokenGenerator.generateAuthorizationCode();
    Nonce nonce = authorizationRequest instanceof AuthenticationRequest ? AuthenticationRequest.class.cast(authorizationRequest).getNonce() : null;
    AuthorizationCode authorizationCode = new AuthorizationCode(code, user.getSub(), client.getClientId(), scopes, redirectionURI, codeChallengeValue, codeChallengeMethodValue, nonce != null ? nonce.getValue() : null, idTokenClaims, redirectionURI != null, tokenValidity(10 * 60));
    authorizationCodeRepository.insert(authorizationCode);
    return authorizationCode;
}
Also used : Nonce(com.nimbusds.openid.connect.sdk.Nonce) AuthorizationCode(oidc.model.AuthorizationCode) Scope(com.nimbusds.oauth2.sdk.Scope) CodeChallengeMethod(com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod) CodeChallenge(com.nimbusds.oauth2.sdk.pkce.CodeChallenge) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) ProvidedRedirectURI(oidc.model.ProvidedRedirectURI) URI(java.net.URI)

Example 2 with CodeChallengeMethod

use of com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod in project OpenConext-oidcng by OpenConext.

the class TokenEndpoint method handleAuthorizationCodeGrant.

private ResponseEntity handleAuthorizationCodeGrant(AuthorizationCodeGrant authorizationCodeGrant, OpenIDClient client) {
    String code = authorizationCodeGrant.getAuthorizationCode().getValue();
    MDCContext.mdcContext("code", "code");
    AuthorizationCode authorizationCode = concurrentAuthorizationCodeRepository.findByCodeNotAlreadyUsedAndMarkAsUsed(code);
    if (authorizationCode == null) {
        /*
             * Now it become's tricky. Did we get an 'null' because the code was bogus or because it was already
             * used? To both satisfy the - highly theoretical - risk of the audit race condition and the OIDC certification
             * demand of deleting access_token issued with the re-used authorization code we need to query again.
             *
             * If they code was bogus this will result in a 404 exception by the authorizationCodeRepository#findByCode
             * and if we find something then we know there was a re-use issue.
             */
        AuthorizationCode byCode = authorizationCodeRepository.findByCode(code);
        accessTokenRepository.deleteByAuthorizationCodeId(byCode.getId());
        throw new TokenAlreadyUsedException("Authorization code already used");
    }
    if (!authorizationCode.getClientId().equals(client.getClientId())) {
        throw new UnauthorizedException("Client is not authorized for the authorization code");
    }
    if (authorizationCodeGrant.getRedirectionURI() != null && !authorizationCodeGrant.getRedirectionURI().toString().equals(authorizationCode.getRedirectUri())) {
        throw new RedirectMismatchException("Redirects do not match");
    }
    if (authorizationCode.isRedirectURIProvided() && authorizationCodeGrant.getRedirectionURI() == null) {
        throw new RedirectMismatchException("Redirect URI is mandatory if specified in code request");
    }
    if (authorizationCode.isExpired(Clock.systemDefaultZone())) {
        throw new UnauthorizedException("Authorization code expired");
    }
    CodeVerifier codeVerifier = authorizationCodeGrant.getCodeVerifier();
    String codeChallenge = authorizationCode.getCodeChallenge();
    if (codeVerifier != null) {
        if (codeChallenge == null) {
            throw new CodeVerifierMissingException("code_verifier present, but no code_challenge in the authorization_code");
        }
        CodeChallengeMethod codeChallengeMethod = CodeChallengeMethod.parse(authorizationCode.getCodeChallengeMethod());
        CodeChallenge computed = CodeChallenge.compute(codeChallengeMethod, codeVerifier);
        // Constant time comparison
        if (!MessageDigest.isEqual(codeChallenge.getBytes(), computed.getValue().getBytes())) {
            LOG.error(String.format("CodeVerifier %s with method %s does not match codeChallenge %s. Expected codeChallenge is %s", codeVerifier.getValue(), codeChallengeMethod, codeChallenge, computed.getValue()));
            throw new CodeVerifierMissingException("code_verifier does not match code_challenge");
        }
    }
    User user = userRepository.findUserBySub(authorizationCode.getSub());
    MDCContext.mdcContext(user);
    // User information is encrypted in access token
    LOG.debug("Deleting user " + user.getSub());
    userRepository.delete(user);
    Map<String, Object> body = tokenEndpointResponse(Optional.of(user), client, authorizationCode.getScopes(), authorizationCode.getIdTokenClaims(), false, authorizationCode.getNonce(), Optional.of(authorizationCode.getAuthTime()), Optional.of(authorizationCode.getId()));
    return new ResponseEntity<>(body, responseHttpHeaders, HttpStatus.OK);
}
Also used : AuthorizationCode(oidc.model.AuthorizationCode) User(oidc.model.User) CodeChallengeMethod(com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod) CodeVerifierMissingException(oidc.exceptions.CodeVerifierMissingException) TokenAlreadyUsedException(oidc.exceptions.TokenAlreadyUsedException) CodeVerifier(com.nimbusds.oauth2.sdk.pkce.CodeVerifier) ResponseEntity(org.springframework.http.ResponseEntity) UnauthorizedException(oidc.exceptions.UnauthorizedException) RedirectMismatchException(oidc.exceptions.RedirectMismatchException) CodeChallenge(com.nimbusds.oauth2.sdk.pkce.CodeChallenge)

Example 3 with CodeChallengeMethod

use of com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod in project java-oauth-server by authlete.

the class Federation method buildAuthenticationRequest.

// ------------------------------------------------------------
// Authentication Request
// ------------------------------------------------------------
private AuthenticationRequest buildAuthenticationRequest(State state, CodeVerifier verifier, CodeChallengeMethod method) throws IOException {
    // The authorization endpoint of the OpenID provider.
    URI endpoint = authorizationEndpoint();
    // response_type
    ResponseType responseType = new ResponseType("code");
    // scope
    Scope scope = buildAuthenticationRequestScope();
    // client_id (from federation configuration)
    ClientID clientId = clientId();
    // redirect_uri (from federation configuration)
    URI redirectUri = redirectUri();
    // Start to build an authentication request.
    AuthenticationRequest.Builder builder = new AuthenticationRequest.Builder(responseType, scope, clientId, redirectUri).endpointURI(endpoint);
    // state
    if (state != null) {
        builder.state(state);
    }
    // code_challenge & code_challenge_method
    if (verifier != null && method != null) {
        // code_challenge is computed from the verifier and the method.
        builder.codeChallenge(verifier, method);
    }
    return builder.build();
}
Also used : Scope(com.nimbusds.oauth2.sdk.Scope) ClientID(com.nimbusds.oauth2.sdk.id.ClientID) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) URI(java.net.URI) ResponseType(com.nimbusds.oauth2.sdk.ResponseType)

Example 4 with CodeChallengeMethod

use of com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod in project java-oauth-server by authlete.

the class Federation method createFederationRequest.

// ------------------------------------------------------------
// Federation Flow
// ------------------------------------------------------------
/**
 * Create an authentication request that is to be sent to the authorization
 * endpoint of the OpenID Provider.
 */
public URI createFederationRequest(String state, String codeVerifier) throws IOException {
    // state
    State st = (state != null) ? new State(state) : null;
    // Code verifier that is to be used to calculate code_challenge.
    CodeVerifier verifier = (codeVerifier != null) ? new CodeVerifier(codeVerifier) : null;
    // code_challenge_method
    CodeChallengeMethod method = (verifier != null) ? CodeChallengeMethod.S256 : null;
    // Create an authentication request that is to be sent to
    // the authorization endpoint.
    AuthenticationRequest request = buildAuthenticationRequest(st, verifier, method);
    return request.toURI();
}
Also used : CodeVerifier(com.nimbusds.oauth2.sdk.pkce.CodeVerifier) CodeChallengeMethod(com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod) State(com.nimbusds.oauth2.sdk.id.State) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest)

Aggregations

CodeChallengeMethod (com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod)3 AuthenticationRequest (com.nimbusds.openid.connect.sdk.AuthenticationRequest)3 Scope (com.nimbusds.oauth2.sdk.Scope)2 CodeChallenge (com.nimbusds.oauth2.sdk.pkce.CodeChallenge)2 CodeVerifier (com.nimbusds.oauth2.sdk.pkce.CodeVerifier)2 URI (java.net.URI)2 AuthorizationCode (oidc.model.AuthorizationCode)2 ResponseType (com.nimbusds.oauth2.sdk.ResponseType)1 ClientID (com.nimbusds.oauth2.sdk.id.ClientID)1 State (com.nimbusds.oauth2.sdk.id.State)1 Nonce (com.nimbusds.openid.connect.sdk.Nonce)1 CodeVerifierMissingException (oidc.exceptions.CodeVerifierMissingException)1 RedirectMismatchException (oidc.exceptions.RedirectMismatchException)1 TokenAlreadyUsedException (oidc.exceptions.TokenAlreadyUsedException)1 UnauthorizedException (oidc.exceptions.UnauthorizedException)1 ProvidedRedirectURI (oidc.model.ProvidedRedirectURI)1 User (oidc.model.User)1 ResponseEntity (org.springframework.http.ResponseEntity)1