parent
d6ba348a59
commit
bc6be86aec
|
@ -31,8 +31,11 @@ import org.springframework.security.oauth2.client.authentication.jwt.ProviderJwt
|
||||||
import org.springframework.security.oauth2.client.authentication.nimbus.NimbusAuthorizationCodeTokenExchanger;
|
import org.springframework.security.oauth2.client.authentication.nimbus.NimbusAuthorizationCodeTokenExchanger;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
|
import org.springframework.security.oauth2.client.token.InMemoryAccessTokenRepository;
|
||||||
|
import org.springframework.security.oauth2.client.token.SecurityTokenRepository;
|
||||||
import org.springframework.security.oauth2.client.user.OAuth2UserService;
|
import org.springframework.security.oauth2.client.user.OAuth2UserService;
|
||||||
import org.springframework.security.oauth2.client.user.nimbus.NimbusOAuth2UserService;
|
import org.springframework.security.oauth2.client.user.nimbus.NimbusOAuth2UserService;
|
||||||
|
import org.springframework.security.oauth2.core.AccessToken;
|
||||||
import org.springframework.security.oauth2.core.http.HttpClientConfig;
|
import org.springframework.security.oauth2.core.http.HttpClientConfig;
|
||||||
import org.springframework.security.oauth2.core.provider.DefaultProviderMetadata;
|
import org.springframework.security.oauth2.core.provider.DefaultProviderMetadata;
|
||||||
import org.springframework.security.oauth2.core.provider.ProviderMetadata;
|
import org.springframework.security.oauth2.core.provider.ProviderMetadata;
|
||||||
|
@ -57,6 +60,7 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
|
||||||
|
|
||||||
private R authorizationResponseMatcher;
|
private R authorizationResponseMatcher;
|
||||||
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger;
|
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger;
|
||||||
|
private SecurityTokenRepository<AccessToken> accessTokenRepository;
|
||||||
private OAuth2UserService userInfoService;
|
private OAuth2UserService userInfoService;
|
||||||
private Map<URI, Class<? extends OAuth2User>> customUserTypes = new HashMap<>();
|
private Map<URI, Class<? extends OAuth2User>> customUserTypes = new HashMap<>();
|
||||||
private Map<URI, String> userNameAttributeNames = new HashMap<>();
|
private Map<URI, String> userNameAttributeNames = new HashMap<>();
|
||||||
|
@ -80,6 +84,12 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuthorizationCodeAuthenticationFilterConfigurer<H, R> accessTokenRepository(SecurityTokenRepository<AccessToken> accessTokenRepository) {
|
||||||
|
Assert.notNull(accessTokenRepository, "accessTokenRepository cannot be null");
|
||||||
|
this.accessTokenRepository = accessTokenRepository;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
AuthorizationCodeAuthenticationFilterConfigurer<H, R> userInfoService(OAuth2UserService userInfoService) {
|
AuthorizationCodeAuthenticationFilterConfigurer<H, R> userInfoService(OAuth2UserService userInfoService) {
|
||||||
Assert.notNull(userInfoService, "userInfoService cannot be null");
|
Assert.notNull(userInfoService, "userInfoService cannot be null");
|
||||||
this.userInfoService = userInfoService;
|
this.userInfoService = userInfoService;
|
||||||
|
@ -124,7 +134,8 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
|
||||||
@Override
|
@Override
|
||||||
public void init(H http) throws Exception {
|
public void init(H http) throws Exception {
|
||||||
AuthorizationCodeAuthenticationProvider authenticationProvider = new AuthorizationCodeAuthenticationProvider(
|
AuthorizationCodeAuthenticationProvider authenticationProvider = new AuthorizationCodeAuthenticationProvider(
|
||||||
this.getAuthorizationCodeTokenExchanger(http), this.getProviderJwtDecoderRegistry(http), this.getUserInfoService(http));
|
this.getAuthorizationCodeTokenExchanger(http), this.getAccessTokenRepository(),
|
||||||
|
this.getProviderJwtDecoderRegistry(http), this.getUserInfoService(http));
|
||||||
if (this.userAuthoritiesMapper != null) {
|
if (this.userAuthoritiesMapper != null) {
|
||||||
authenticationProvider.setAuthoritiesMapper(this.userAuthoritiesMapper);
|
authenticationProvider.setAuthoritiesMapper(this.userAuthoritiesMapper);
|
||||||
}
|
}
|
||||||
|
@ -161,6 +172,13 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
|
||||||
return this.authorizationCodeTokenExchanger;
|
return this.authorizationCodeTokenExchanger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SecurityTokenRepository<AccessToken> getAccessTokenRepository() {
|
||||||
|
if (this.accessTokenRepository == null) {
|
||||||
|
this.accessTokenRepository = new InMemoryAccessTokenRepository();
|
||||||
|
}
|
||||||
|
return this.accessTokenRepository;
|
||||||
|
}
|
||||||
|
|
||||||
private ProviderJwtDecoderRegistry getProviderJwtDecoderRegistry(H http) {
|
private ProviderJwtDecoderRegistry getProviderJwtDecoderRegistry(H http) {
|
||||||
HttpClientConfig httpClientConfig = this.getHttpClientConfig(http);
|
HttpClientConfig httpClientConfig = this.getHttpClientConfig(http);
|
||||||
Map<ProviderMetadata, JwtDecoder> jwtDecoders = new HashMap<>();
|
Map<ProviderMetadata, JwtDecoder> jwtDecoders = new HashMap<>();
|
||||||
|
|
|
@ -26,7 +26,9 @@ import org.springframework.security.oauth2.client.authentication.AuthorizationRe
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
|
||||||
|
import org.springframework.security.oauth2.client.token.SecurityTokenRepository;
|
||||||
import org.springframework.security.oauth2.client.user.OAuth2UserService;
|
import org.springframework.security.oauth2.client.user.OAuth2UserService;
|
||||||
|
import org.springframework.security.oauth2.core.AccessToken;
|
||||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||||
|
@ -139,6 +141,12 @@ public final class OAuth2LoginConfigurer<H extends HttpSecurityBuilder<H>> exten
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TokenEndpointConfig accessTokenRepository(SecurityTokenRepository<AccessToken> accessTokenRepository) {
|
||||||
|
Assert.notNull(accessTokenRepository, "accessTokenRepository cannot be null");
|
||||||
|
OAuth2LoginConfigurer.this.authorizationCodeAuthenticationFilterConfigurer.accessTokenRepository(accessTokenRepository);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public OAuth2LoginConfigurer<H> and() {
|
public OAuth2LoginConfigurer<H> and() {
|
||||||
return OAuth2LoginConfigurer.this;
|
return OAuth2LoginConfigurer.this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.springframework.security.jwt.Jwt;
|
||||||
import org.springframework.security.jwt.JwtDecoder;
|
import org.springframework.security.jwt.JwtDecoder;
|
||||||
import org.springframework.security.oauth2.client.authentication.jwt.ProviderJwtDecoderRegistry;
|
import org.springframework.security.oauth2.client.authentication.jwt.ProviderJwtDecoderRegistry;
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||||
|
import org.springframework.security.oauth2.client.token.SecurityTokenRepository;
|
||||||
import org.springframework.security.oauth2.client.user.OAuth2UserService;
|
import org.springframework.security.oauth2.client.user.OAuth2UserService;
|
||||||
import org.springframework.security.oauth2.core.AccessToken;
|
import org.springframework.security.oauth2.core.AccessToken;
|
||||||
import org.springframework.security.oauth2.core.endpoint.TokenResponseAttributes;
|
import org.springframework.security.oauth2.core.endpoint.TokenResponseAttributes;
|
||||||
|
@ -79,19 +80,23 @@ import java.util.Collection;
|
||||||
*/
|
*/
|
||||||
public class AuthorizationCodeAuthenticationProvider implements AuthenticationProvider {
|
public class AuthorizationCodeAuthenticationProvider implements AuthenticationProvider {
|
||||||
private final AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger;
|
private final AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger;
|
||||||
|
private final SecurityTokenRepository<AccessToken> accessTokenRepository;
|
||||||
private final ProviderJwtDecoderRegistry providerJwtDecoderRegistry;
|
private final ProviderJwtDecoderRegistry providerJwtDecoderRegistry;
|
||||||
private final OAuth2UserService userInfoService;
|
private final OAuth2UserService userInfoService;
|
||||||
private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
|
private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
|
||||||
|
|
||||||
public AuthorizationCodeAuthenticationProvider(
|
public AuthorizationCodeAuthenticationProvider(
|
||||||
AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger,
|
AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger,
|
||||||
|
SecurityTokenRepository<AccessToken> accessTokenRepository,
|
||||||
ProviderJwtDecoderRegistry providerJwtDecoderRegistry,
|
ProviderJwtDecoderRegistry providerJwtDecoderRegistry,
|
||||||
OAuth2UserService userInfoService) {
|
OAuth2UserService userInfoService) {
|
||||||
|
|
||||||
Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null");
|
Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null");
|
||||||
|
Assert.notNull(accessTokenRepository, "accessTokenRepository cannot be null");
|
||||||
Assert.notNull(providerJwtDecoderRegistry, "providerJwtDecoderRegistry cannot be null");
|
Assert.notNull(providerJwtDecoderRegistry, "providerJwtDecoderRegistry cannot be null");
|
||||||
Assert.notNull(userInfoService, "userInfoService cannot be null");
|
Assert.notNull(userInfoService, "userInfoService cannot be null");
|
||||||
this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger;
|
this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger;
|
||||||
|
this.accessTokenRepository = accessTokenRepository;
|
||||||
this.providerJwtDecoderRegistry = providerJwtDecoderRegistry;
|
this.providerJwtDecoderRegistry = providerJwtDecoderRegistry;
|
||||||
this.userInfoService = userInfoService;
|
this.userInfoService = userInfoService;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +139,8 @@ public class AuthorizationCodeAuthenticationProvider implements AuthenticationPr
|
||||||
accessTokenAuthentication.getAccessToken(), accessTokenAuthentication.getIdToken());
|
accessTokenAuthentication.getAccessToken(), accessTokenAuthentication.getIdToken());
|
||||||
authenticationResult.setDetails(accessTokenAuthentication.getDetails());
|
authenticationResult.setDetails(accessTokenAuthentication.getDetails());
|
||||||
|
|
||||||
|
this.accessTokenRepository.saveSecurityToken(accessToken, authenticationResult);
|
||||||
|
|
||||||
return authenticationResult;
|
return authenticationResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2017 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.security.oauth2.client.token;
|
||||||
|
|
||||||
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||||
|
import org.springframework.security.oauth2.core.AccessToken;
|
||||||
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||||
|
import org.springframework.security.oauth2.oidc.core.user.OidcUser;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A basic implementation of a {@link SecurityTokenRepository}
|
||||||
|
* that stores {@link AccessToken}(s) <i>in-memory</i>.
|
||||||
|
*
|
||||||
|
* @author Joe Grandja
|
||||||
|
* @since 5.0
|
||||||
|
* @see SecurityTokenRepository
|
||||||
|
* @see AccessToken
|
||||||
|
*/
|
||||||
|
public final class InMemoryAccessTokenRepository implements SecurityTokenRepository<AccessToken> {
|
||||||
|
private final Map<String, AccessToken> accessTokens = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessToken loadSecurityToken(OAuth2AuthenticationToken authentication) {
|
||||||
|
Assert.notNull(authentication, "authentication cannot be null");
|
||||||
|
return this.accessTokens.get(this.resolveAuthenticationKey(authentication));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveSecurityToken(AccessToken accessToken, OAuth2AuthenticationToken authentication) {
|
||||||
|
Assert.notNull(accessToken, "accessToken cannot be null");
|
||||||
|
Assert.notNull(authentication, "authentication cannot be null");
|
||||||
|
this.accessTokens.put(this.resolveAuthenticationKey(authentication), accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeSecurityToken(OAuth2AuthenticationToken authentication) {
|
||||||
|
Assert.notNull(authentication, "authentication cannot be null");
|
||||||
|
this.accessTokens.remove(this.resolveAuthenticationKey(authentication));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveAuthenticationKey(OAuth2AuthenticationToken authentication) {
|
||||||
|
String authenticationKey;
|
||||||
|
|
||||||
|
OAuth2User oauth2User = (OAuth2User) authentication.getPrincipal();
|
||||||
|
if (OidcUser.class.isAssignableFrom(oauth2User.getClass())) {
|
||||||
|
OidcUser oidcUser = (OidcUser)oauth2User;
|
||||||
|
authenticationKey = oidcUser.getIssuer().toString() + "-" + oidcUser.getSubject();
|
||||||
|
} else {
|
||||||
|
authenticationKey = authentication.getClientRegistration().getProviderDetails().getUserInfoUri() +
|
||||||
|
"-" + oauth2User.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticationKey;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue