@Override public Mono<Authentication> authenticate(Authentication authentication) { return Mono.defer(() -> { OAuth2AuthorizationCodeAuthenticationToken token = (OAuth2AuthorizationCodeAuthenticationToken) authentication; OAuth2AuthorizationExchangeValidator.validate(token.getAuthorizationExchange()); OAuth2AuthorizationCodeGrantRequest authzRequest = new OAuth2AuthorizationCodeGrantRequest( token.getClientRegistration(), token.getAuthorizationExchange()); return this.accessTokenResponseClient.getTokenResponse(authzRequest) .map(onSuccess(token)); }); }
@Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { OAuth2AuthorizationCodeAuthenticationToken authorizationCodeAuthentication = (OAuth2AuthorizationCodeAuthenticationToken) authentication; OAuth2AuthorizationExchangeValidator.validate( authorizationCodeAuthentication.getAuthorizationExchange()); OAuth2AccessTokenResponse accessTokenResponse = this.accessTokenResponseClient.getTokenResponse( new OAuth2AuthorizationCodeGrantRequest( authorizationCodeAuthentication.getClientRegistration(), authorizationCodeAuthentication.getAuthorizationExchange())); OAuth2AuthorizationCodeAuthenticationToken authenticationResult = new OAuth2AuthorizationCodeAuthenticationToken( authorizationCodeAuthentication.getClientRegistration(), authorizationCodeAuthentication.getAuthorizationExchange(), accessTokenResponse.getAccessToken(), accessTokenResponse.getRefreshToken()); authenticationResult.setDetails(authorizationCodeAuthentication.getDetails()); return authenticationResult; }
private Function<OAuth2AccessTokenResponse, OAuth2AuthorizationCodeAuthenticationToken> onSuccess(OAuth2AuthorizationCodeAuthenticationToken token) { return accessTokenResponse -> { ClientRegistration registration = token.getClientRegistration(); OAuth2AuthorizationExchange exchange = token.getAuthorizationExchange(); OAuth2AccessToken accessToken = accessTokenResponse.getAccessToken(); OAuth2RefreshToken refreshToken = accessTokenResponse.getRefreshToken(); return new OAuth2AuthorizationCodeAuthenticationToken(registration, exchange, accessToken, refreshToken, accessTokenResponse.getAdditionalParameters()); }; } }
@Test public void applyWhenCodeParameterNotFoundThenErrorCode() { this.request.queryParam(OAuth2ParameterNames.ERROR, "error"); when(this.authorizationRequestRepository.removeAuthorizationRequest(any())).thenReturn(Mono.just(this.authorizationRequest.build())); when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(Mono.just(this.clientRegistration)); assertThat(applyConverter().getAuthorizationExchange().getAuthorizationResponse().getError().getErrorCode()) .isEqualTo("error"); }
@Test public void constructorTokenRequestResponseWhenAllParametersProvidedAndValidThenCreated() { OAuth2AuthorizationCodeAuthenticationToken authentication = new OAuth2AuthorizationCodeAuthenticationToken( this.clientRegistration, this.authorizationExchange, this.accessToken); assertThat(authentication.getPrincipal()).isEqualTo(this.clientRegistration.getClientId()); assertThat(authentication.getCredentials()).isEqualTo(this.accessToken.getTokenValue()); assertThat(authentication.getAuthorities()).isEqualTo(Collections.emptyList()); assertThat(authentication.getClientRegistration()).isEqualTo(this.clientRegistration); assertThat(authentication.getAuthorizationExchange()).isEqualTo(this.authorizationExchange); assertThat(authentication.getAccessToken()).isEqualTo(this.accessToken); assertThat(authentication.isAuthenticated()).isEqualTo(true); } }
@Test public void applyWhenCodeParameterFoundThenCode() { this.request.queryParam(OAuth2ParameterNames.CODE, "code"); when(this.authorizationRequestRepository.removeAuthorizationRequest(any())).thenReturn(Mono.just(this.authorizationRequest.build())); when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn(Mono.just(this.clientRegistration)); OAuth2AuthorizationCodeAuthenticationToken result = applyConverter(); OAuth2AuthorizationResponse exchange = result .getAuthorizationExchange().getAuthorizationResponse(); assertThat(exchange.getError()).isNull(); assertThat(exchange.getCode()).isEqualTo("code"); }
@Test public void constructorAuthorizationRequestResponseWhenAllParametersProvidedAndValidThenCreated() { OAuth2AuthorizationCodeAuthenticationToken authentication = new OAuth2AuthorizationCodeAuthenticationToken(this.clientRegistration, this.authorizationExchange); assertThat(authentication.getPrincipal()).isEqualTo(this.clientRegistration.getClientId()); assertThat(authentication.getCredentials()).isEqualTo(this.authorizationExchange.getAuthorizationResponse().getCode()); assertThat(authentication.getAuthorities()).isEqualTo(Collections.emptyList()); assertThat(authentication.getClientRegistration()).isEqualTo(this.clientRegistration); assertThat(authentication.getAuthorizationExchange()).isEqualTo(this.authorizationExchange); assertThat(authentication.getAccessToken()).isNull(); assertThat(authentication.isAuthenticated()).isEqualTo(false); }
@Override public Mono<Authentication> authenticate(Authentication authentication) { return Mono.defer(() -> { OAuth2AuthorizationCodeAuthenticationToken token = (OAuth2AuthorizationCodeAuthenticationToken) authentication; // Section 3.1.2.1 Authentication Request - http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest // scope REQUIRED. OpenID Connect requests MUST contain the "openid" scope value. if (token.getAuthorizationExchange() .getAuthorizationRequest().getScopes().contains("openid")) { // This is an OpenID Connect Authentication Request so return null // and let OidcAuthorizationCodeReactiveAuthenticationManager handle it instead once one is created // FIXME: Once we create OidcAuthorizationCodeReactiveAuthenticationManager uncomment below // return Mono.empty(); } return this.authorizationCodeManager.authenticate(token) .onErrorMap(OAuth2AuthorizationException.class, e -> new OAuth2AuthenticationException(e.getError(), e.getError().toString())) .cast(OAuth2AuthorizationCodeAuthenticationToken.class) .flatMap(this::onSuccess); }); }
private Mono<OAuth2LoginAuthenticationToken> authenticationResult(OAuth2AuthorizationCodeAuthenticationToken authorizationCodeAuthentication, OAuth2AccessTokenResponse accessTokenResponse) { OAuth2AccessToken accessToken = accessTokenResponse.getAccessToken(); ClientRegistration clientRegistration = authorizationCodeAuthentication.getClientRegistration(); Map<String, Object> additionalParameters = accessTokenResponse.getAdditionalParameters(); if (!additionalParameters.containsKey(OidcParameterNames.ID_TOKEN)) { OAuth2Error invalidIdTokenError = new OAuth2Error( INVALID_ID_TOKEN_ERROR_CODE, "Missing (required) ID Token in Token Response for Client Registration: " + clientRegistration.getRegistrationId(), null); throw new OAuth2AuthenticationException(invalidIdTokenError, invalidIdTokenError.toString()); } return createOidcToken(clientRegistration, accessTokenResponse) .map(idToken -> new OidcUserRequest(clientRegistration, accessToken, idToken, additionalParameters)) .flatMap(this.userService::loadUser) .map(oauth2User -> { Collection<? extends GrantedAuthority> mappedAuthorities = this.authoritiesMapper.mapAuthorities(oauth2User.getAuthorities()); return new OAuth2LoginAuthenticationToken( authorizationCodeAuthentication.getClientRegistration(), authorizationCodeAuthentication.getAuthorizationExchange(), oauth2User, mappedAuthorities, accessToken, accessTokenResponse.getRefreshToken()); }); }
@Test public void authenticateWhenAuthorizationSuccessResponseThenExchangedForAccessToken() { OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().refreshToken("refresh").build(); when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse); OAuth2AuthorizationExchange authorizationExchange = new OAuth2AuthorizationExchange( this.authorizationRequest, success().build()); OAuth2AuthorizationCodeAuthenticationToken authenticationResult = (OAuth2AuthorizationCodeAuthenticationToken) this.authenticationProvider.authenticate( new OAuth2AuthorizationCodeAuthenticationToken(this.clientRegistration, authorizationExchange)); assertThat(authenticationResult.isAuthenticated()).isTrue(); assertThat(authenticationResult.getPrincipal()).isEqualTo(this.clientRegistration.getClientId()); assertThat(authenticationResult.getCredentials()) .isEqualTo(accessTokenResponse.getAccessToken().getTokenValue()); assertThat(authenticationResult.getAuthorities()).isEqualTo(Collections.emptyList()); assertThat(authenticationResult.getClientRegistration()).isEqualTo(this.clientRegistration); assertThat(authenticationResult.getAuthorizationExchange()).isEqualTo(authorizationExchange); assertThat(authenticationResult.getAccessToken()).isEqualTo(accessTokenResponse.getAccessToken()); assertThat(authenticationResult.getRefreshToken()).isEqualTo(accessTokenResponse.getRefreshToken()); } }
private Mono<OAuth2LoginAuthenticationToken> onSuccess(OAuth2AuthorizationCodeAuthenticationToken authentication) { OAuth2AccessToken accessToken = authentication.getAccessToken(); Map<String, Object> additionalParameters = authentication.getAdditionalParameters(); OAuth2UserRequest userRequest = new OAuth2UserRequest(authentication.getClientRegistration(), accessToken, additionalParameters); return this.userService.loadUser(userRequest) .map(oauth2User -> { Collection<? extends GrantedAuthority> mappedAuthorities = this.authoritiesMapper.mapAuthorities(oauth2User.getAuthorities()); OAuth2LoginAuthenticationToken authenticationResult = new OAuth2LoginAuthenticationToken( authentication.getClientRegistration(), authentication.getAuthorizationExchange(), oauth2User, mappedAuthorities, accessToken, authentication.getRefreshToken()); return authenticationResult; }); } }
if (!authorizationCodeAuthentication.getAuthorizationExchange() .getAuthorizationRequest().getScopes().contains("openid")) { .getAuthorizationExchange().getAuthorizationRequest(); OAuth2AuthorizationResponse authorizationResponse = authorizationCodeAuthentication .getAuthorizationExchange().getAuthorizationResponse(); authorizationCodeAuthentication.getAuthorizationExchange());
@Override public Mono<Authentication> authenticate(Authentication authentication) { return Mono.defer(() -> { OAuth2AuthorizationCodeAuthenticationToken token = (OAuth2AuthorizationCodeAuthenticationToken) authentication; OAuth2AuthorizationExchangeValidator.validate(token.getAuthorizationExchange()); OAuth2AuthorizationCodeGrantRequest authzRequest = new OAuth2AuthorizationCodeGrantRequest( token.getClientRegistration(), token.getAuthorizationExchange()); return this.accessTokenResponseClient.getTokenResponse(authzRequest) .map(onSuccess(token)); }); }
@Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { OAuth2AuthorizationCodeAuthenticationToken authorizationCodeAuthentication = (OAuth2AuthorizationCodeAuthenticationToken) authentication; OAuth2AuthorizationExchangeValidator.validate( authorizationCodeAuthentication.getAuthorizationExchange()); OAuth2AccessTokenResponse accessTokenResponse = this.accessTokenResponseClient.getTokenResponse( new OAuth2AuthorizationCodeGrantRequest( authorizationCodeAuthentication.getClientRegistration(), authorizationCodeAuthentication.getAuthorizationExchange())); OAuth2AuthorizationCodeAuthenticationToken authenticationResult = new OAuth2AuthorizationCodeAuthenticationToken( authorizationCodeAuthentication.getClientRegistration(), authorizationCodeAuthentication.getAuthorizationExchange(), accessTokenResponse.getAccessToken(), accessTokenResponse.getRefreshToken()); authenticationResult.setDetails(authorizationCodeAuthentication.getDetails()); return authenticationResult; }
private Function<OAuth2AccessTokenResponse, OAuth2AuthorizationCodeAuthenticationToken> onSuccess(OAuth2AuthorizationCodeAuthenticationToken token) { return accessTokenResponse -> { ClientRegistration registration = token.getClientRegistration(); OAuth2AuthorizationExchange exchange = token.getAuthorizationExchange(); OAuth2AccessToken accessToken = accessTokenResponse.getAccessToken(); OAuth2RefreshToken refreshToken = accessTokenResponse.getRefreshToken(); return new OAuth2AuthorizationCodeAuthenticationToken(registration, exchange, accessToken, refreshToken, accessTokenResponse.getAdditionalParameters()); }; } }
@Override public Mono<Authentication> authenticate(Authentication authentication) { return Mono.defer(() -> { OAuth2AuthorizationCodeAuthenticationToken token = (OAuth2AuthorizationCodeAuthenticationToken) authentication; // Section 3.1.2.1 Authentication Request - http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest // scope REQUIRED. OpenID Connect requests MUST contain the "openid" scope value. if (token.getAuthorizationExchange() .getAuthorizationRequest().getScopes().contains("openid")) { // This is an OpenID Connect Authentication Request so return null // and let OidcAuthorizationCodeReactiveAuthenticationManager handle it instead once one is created // FIXME: Once we create OidcAuthorizationCodeReactiveAuthenticationManager uncomment below // return Mono.empty(); } return this.authorizationCodeManager.authenticate(token) .onErrorMap(OAuth2AuthorizationException.class, e -> new OAuth2AuthenticationException(e.getError(), e.getError().toString())) .cast(OAuth2AuthorizationCodeAuthenticationToken.class) .flatMap(this::onSuccess); }); }
private Mono<OAuth2LoginAuthenticationToken> authenticationResult(OAuth2AuthorizationCodeAuthenticationToken authorizationCodeAuthentication, OAuth2AccessTokenResponse accessTokenResponse) { OAuth2AccessToken accessToken = accessTokenResponse.getAccessToken(); ClientRegistration clientRegistration = authorizationCodeAuthentication.getClientRegistration(); Map<String, Object> additionalParameters = accessTokenResponse.getAdditionalParameters(); if (!additionalParameters.containsKey(OidcParameterNames.ID_TOKEN)) { OAuth2Error invalidIdTokenError = new OAuth2Error( INVALID_ID_TOKEN_ERROR_CODE, "Missing (required) ID Token in Token Response for Client Registration: " + clientRegistration.getRegistrationId(), null); throw new OAuth2AuthenticationException(invalidIdTokenError, invalidIdTokenError.toString()); } return createOidcToken(clientRegistration, accessTokenResponse) .map(idToken -> new OidcUserRequest(clientRegistration, accessToken, idToken, additionalParameters)) .flatMap(this.userService::loadUser) .map(oauth2User -> { Collection<? extends GrantedAuthority> mappedAuthorities = this.authoritiesMapper.mapAuthorities(oauth2User.getAuthorities()); return new OAuth2LoginAuthenticationToken( authorizationCodeAuthentication.getClientRegistration(), authorizationCodeAuthentication.getAuthorizationExchange(), oauth2User, mappedAuthorities, accessToken, accessTokenResponse.getRefreshToken()); }); }
if (!authorizationCodeAuthentication.getAuthorizationExchange() .getAuthorizationRequest().getScopes().contains("openid")) { .getAuthorizationExchange().getAuthorizationRequest(); OAuth2AuthorizationResponse authorizationResponse = authorizationCodeAuthentication .getAuthorizationExchange().getAuthorizationResponse(); authorizationCodeAuthentication.getAuthorizationExchange());
private Mono<OAuth2LoginAuthenticationToken> onSuccess(OAuth2AuthorizationCodeAuthenticationToken authentication) { OAuth2AccessToken accessToken = authentication.getAccessToken(); Map<String, Object> additionalParameters = authentication.getAdditionalParameters(); OAuth2UserRequest userRequest = new OAuth2UserRequest(authentication.getClientRegistration(), accessToken, additionalParameters); return this.userService.loadUser(userRequest) .map(oauth2User -> { Collection<? extends GrantedAuthority> mappedAuthorities = this.authoritiesMapper.mapAuthorities(oauth2User.getAuthorities()); OAuth2LoginAuthenticationToken authenticationResult = new OAuth2LoginAuthenticationToken( authentication.getClientRegistration(), authentication.getAuthorizationExchange(), oauth2User, mappedAuthorities, accessToken, authentication.getRefreshToken()); return authenticationResult; }); } }