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);
}
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();
}
Aggregations