Search in sources :

Example 1 with OAuth2AuthenticationValidator

use of org.springframework.security.oauth2.core.authentication.OAuth2AuthenticationValidator in project spring-authorization-server by spring-projects.

the class OAuth2AuthorizationCodeRequestAuthenticationProviderTests method authenticateWhenCustomAuthenticationValidatorResolverThenUsed.

@Test
public void authenticateWhenCustomAuthenticationValidatorResolverThenUsed() {
    RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
    when(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId()))).thenReturn(registeredClient);
    @SuppressWarnings("unchecked") Function<String, OAuth2AuthenticationValidator> authenticationValidatorResolver = mock(Function.class);
    this.authenticationProvider.setAuthenticationValidatorResolver(authenticationValidatorResolver);
    OAuth2AuthorizationCodeRequestAuthenticationToken authentication = authorizationCodeRequestAuthentication(registeredClient, this.principal).build();
    OAuth2AuthorizationCodeRequestAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeRequestAuthenticationToken) this.authenticationProvider.authenticate(authentication);
    assertAuthorizationCodeRequestWithAuthorizationCodeResult(registeredClient, authentication, authenticationResult);
    ArgumentCaptor<String> parameterNameCaptor = ArgumentCaptor.forClass(String.class);
    verify(authenticationValidatorResolver, times(2)).apply(parameterNameCaptor.capture());
    assertThat(parameterNameCaptor.getAllValues()).containsExactly(OAuth2ParameterNames.REDIRECT_URI, OAuth2ParameterNames.SCOPE);
}
Also used : OAuth2AuthenticationValidator(org.springframework.security.oauth2.core.authentication.OAuth2AuthenticationValidator) RegisteredClient(org.springframework.security.oauth2.server.authorization.client.RegisteredClient) Test(org.junit.Test)

Example 2 with OAuth2AuthenticationValidator

use of org.springframework.security.oauth2.core.authentication.OAuth2AuthenticationValidator in project spring-authorization-server by spring-projects.

the class OAuth2AuthorizationCodeRequestAuthenticationProvider method authenticateAuthorizationRequest.

private Authentication authenticateAuthorizationRequest(Authentication authentication) throws AuthenticationException {
    OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthentication = (OAuth2AuthorizationCodeRequestAuthenticationToken) authentication;
    RegisteredClient registeredClient = this.registeredClientRepository.findByClientId(authorizationCodeRequestAuthentication.getClientId());
    if (registeredClient == null) {
        throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.CLIENT_ID, authorizationCodeRequestAuthentication, null);
    }
    Map<Object, Object> context = new HashMap<>();
    context.put(RegisteredClient.class, registeredClient);
    OAuth2AuthenticationContext authenticationContext = new OAuth2AuthenticationContext(authorizationCodeRequestAuthentication, context);
    OAuth2AuthenticationValidator redirectUriValidator = resolveAuthenticationValidator(OAuth2ParameterNames.REDIRECT_URI);
    redirectUriValidator.validate(authenticationContext);
    if (!registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.AUTHORIZATION_CODE)) {
        throwError(OAuth2ErrorCodes.UNAUTHORIZED_CLIENT, OAuth2ParameterNames.CLIENT_ID, authorizationCodeRequestAuthentication, registeredClient);
    }
    OAuth2AuthenticationValidator scopeValidator = resolveAuthenticationValidator(OAuth2ParameterNames.SCOPE);
    scopeValidator.validate(authenticationContext);
    // code_challenge (REQUIRED for public clients) - RFC 7636 (PKCE)
    String codeChallenge = (String) authorizationCodeRequestAuthentication.getAdditionalParameters().get(PkceParameterNames.CODE_CHALLENGE);
    if (StringUtils.hasText(codeChallenge)) {
        String codeChallengeMethod = (String) authorizationCodeRequestAuthentication.getAdditionalParameters().get(PkceParameterNames.CODE_CHALLENGE_METHOD);
        if (StringUtils.hasText(codeChallengeMethod)) {
            if (!"S256".equals(codeChallengeMethod) && !"plain".equals(codeChallengeMethod)) {
                throwError(OAuth2ErrorCodes.INVALID_REQUEST, PkceParameterNames.CODE_CHALLENGE_METHOD, PKCE_ERROR_URI, authorizationCodeRequestAuthentication, registeredClient, null);
            }
        }
    } else if (registeredClient.getClientSettings().isRequireProofKey()) {
        throwError(OAuth2ErrorCodes.INVALID_REQUEST, PkceParameterNames.CODE_CHALLENGE, PKCE_ERROR_URI, authorizationCodeRequestAuthentication, registeredClient, null);
    }
    // ---------------
    // The request is valid - ensure the resource owner is authenticated
    // ---------------
    Authentication principal = (Authentication) authorizationCodeRequestAuthentication.getPrincipal();
    if (!isPrincipalAuthenticated(principal)) {
        // Return the authorization request as-is where isAuthenticated() is false
        return authorizationCodeRequestAuthentication;
    }
    OAuth2AuthorizationRequest authorizationRequest = OAuth2AuthorizationRequest.authorizationCode().authorizationUri(authorizationCodeRequestAuthentication.getAuthorizationUri()).clientId(registeredClient.getClientId()).redirectUri(authorizationCodeRequestAuthentication.getRedirectUri()).scopes(authorizationCodeRequestAuthentication.getScopes()).state(authorizationCodeRequestAuthentication.getState()).additionalParameters(authorizationCodeRequestAuthentication.getAdditionalParameters()).build();
    OAuth2AuthorizationConsent currentAuthorizationConsent = this.authorizationConsentService.findById(registeredClient.getId(), principal.getName());
    if (requireAuthorizationConsent(registeredClient, authorizationRequest, currentAuthorizationConsent)) {
        String state = DEFAULT_STATE_GENERATOR.generateKey();
        OAuth2Authorization authorization = authorizationBuilder(registeredClient, principal, authorizationRequest).attribute(OAuth2ParameterNames.STATE, state).build();
        this.authorizationService.save(authorization);
        // TODO Need to remove 'in-flight' authorization if consent step is not completed (e.g. approved or cancelled)
        Set<String> currentAuthorizedScopes = currentAuthorizationConsent != null ? currentAuthorizationConsent.getScopes() : null;
        return OAuth2AuthorizationCodeRequestAuthenticationToken.with(registeredClient.getClientId(), principal).authorizationUri(authorizationRequest.getAuthorizationUri()).scopes(currentAuthorizedScopes).state(state).consentRequired(true).build();
    }
    OAuth2AuthorizationCode authorizationCode;
    if (this.authorizationCodeSupplier != null) {
        Instant issuedAt = Instant.now();
        // TODO Allow configuration for authorization code time-to-live
        Instant expiresAt = issuedAt.plus(5, ChronoUnit.MINUTES);
        authorizationCode = new OAuth2AuthorizationCode(this.authorizationCodeSupplier.get(), issuedAt, expiresAt);
    } else {
        OAuth2TokenContext tokenContext = createAuthorizationCodeTokenContext(authorizationCodeRequestAuthentication, registeredClient, null, authorizationRequest.getScopes());
        authorizationCode = this.authorizationCodeGenerator.generate(tokenContext);
        if (authorizationCode == null) {
            OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.SERVER_ERROR, "The token generator failed to generate the authorization code.", ERROR_URI);
            throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
        }
    }
    OAuth2Authorization authorization = authorizationBuilder(registeredClient, principal, authorizationRequest).token(authorizationCode).attribute(OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME, authorizationRequest.getScopes()).build();
    this.authorizationService.save(authorization);
    String redirectUri = authorizationRequest.getRedirectUri();
    if (!StringUtils.hasText(redirectUri)) {
        redirectUri = registeredClient.getRedirectUris().iterator().next();
    }
    return OAuth2AuthorizationCodeRequestAuthenticationToken.with(registeredClient.getClientId(), principal).authorizationUri(authorizationRequest.getAuthorizationUri()).redirectUri(redirectUri).scopes(authorizationRequest.getScopes()).state(authorizationRequest.getState()).authorizationCode(authorizationCode).build();
}
Also used : HashMap(java.util.HashMap) Instant(java.time.Instant) OAuth2AuthorizationConsent(org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent) OAuth2Authorization(org.springframework.security.oauth2.server.authorization.OAuth2Authorization) OAuth2Error(org.springframework.security.oauth2.core.OAuth2Error) OAuth2AuthenticationContext(org.springframework.security.oauth2.core.authentication.OAuth2AuthenticationContext) RegisteredClient(org.springframework.security.oauth2.server.authorization.client.RegisteredClient) OAuth2AuthenticationValidator(org.springframework.security.oauth2.core.authentication.OAuth2AuthenticationValidator) DefaultOAuth2TokenContext(org.springframework.security.oauth2.server.authorization.DefaultOAuth2TokenContext) OAuth2TokenContext(org.springframework.security.oauth2.server.authorization.OAuth2TokenContext) Authentication(org.springframework.security.core.Authentication) OAuth2AuthorizationCode(org.springframework.security.oauth2.core.OAuth2AuthorizationCode) OAuth2AuthorizationRequest(org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest)

Aggregations

OAuth2AuthenticationValidator (org.springframework.security.oauth2.core.authentication.OAuth2AuthenticationValidator)2 RegisteredClient (org.springframework.security.oauth2.server.authorization.client.RegisteredClient)2 Instant (java.time.Instant)1 HashMap (java.util.HashMap)1 Test (org.junit.Test)1 Authentication (org.springframework.security.core.Authentication)1 OAuth2AuthorizationCode (org.springframework.security.oauth2.core.OAuth2AuthorizationCode)1 OAuth2Error (org.springframework.security.oauth2.core.OAuth2Error)1 OAuth2AuthenticationContext (org.springframework.security.oauth2.core.authentication.OAuth2AuthenticationContext)1 OAuth2AuthorizationRequest (org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest)1 DefaultOAuth2TokenContext (org.springframework.security.oauth2.server.authorization.DefaultOAuth2TokenContext)1 OAuth2Authorization (org.springframework.security.oauth2.server.authorization.OAuth2Authorization)1 OAuth2AuthorizationConsent (org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent)1 OAuth2TokenContext (org.springframework.security.oauth2.server.authorization.OAuth2TokenContext)1