spring security oauth2 使用说明
spring security oauth2实现了oauth2协议,可搭建client(客户端)、resource server(资源服务器)、authorization server(认证服务器),
其中client(客户端)可用来实现三方登陆,spring-security-oauth2-client默认集成了github、google、facebook、okta,也提供了一些接口,可实现支付宝、qq、微信等三方授权登录
**************************
相关 jar 包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>5.3.1.RELEASE</version>
</dependency>
**************************
配置类
OAuth2ClientAutoConfiguration:客户端自动配置类
@Configuration(
proxyBeanMethods = false
)
@AutoConfigureBefore({SecurityAutoConfiguration.class})
@ConditionalOnClass({EnableWebSecurity.class, ClientRegistration.class})
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@Import({OAuth2ClientRegistrationRepositoryConfiguration.class, OAuth2WebSecurityConfiguration.class})
public class OAuth2ClientAutoConfiguration {
public OAuth2ClientAutoConfiguration() {
}
}
说明:该自动配置类导入OAuth2ClientRegistrationRepositoryConfiguration、OAuth2WebSecurityConfiguration
OAuth2ClientRegistrationRepositoryConfiguration:客户端配置类
@Configuration(
proxyBeanMethods = false
)
@EnableConfigurationProperties({OAuth2ClientProperties.class})
@Conditional({ClientsConfiguredCondition.class})
class OAuth2ClientRegistrationRepositoryConfiguration {
OAuth2ClientRegistrationRepositoryConfiguration() {
}
@Bean
@ConditionalOnMissingBean({ClientRegistrationRepository.class})
InMemoryClientRegistrationRepository clientRegistrationRepository(OAuth2ClientProperties properties) {
List<ClientRegistration> registrations = new ArrayList(OAuth2ClientPropertiesRegistrationAdapter.getClientRegistrations(properties).values());
return new InMemoryClientRegistrationRepository(registrations);
}//如果不存在ClientRegistrationRepository实例,则创建InMemoryClientRegistrationRepository实例
}
OAuth2ClientProperties:自动配置属性
@ConfigurationProperties(
prefix = "spring.security.oauth2.client"
)
public class OAuth2ClientProperties {
private final Map<String, OAuth2ClientProperties.Provider> provider = new HashMap();
private final Map<String, OAuth2ClientProperties.Registration> registration = new HashMap();
*****************
内部类
public static class Provider {
private String authorizationUri;
private String tokenUri;
private String userInfoUri;
private String userInfoAuthenticationMethod;
private String userNameAttribute;
private String jwkSetUri;
private String issuerUri;
*****************
内部类
public static class Registration {
private String provider;
private String clientId;
private String clientSecret;
private String clientAuthenticationMethod;
private String authorizationGrantType;
private String redirectUri;
private Set<String> scope;
private String clientName;
ClientRegistrationRepository:根据registrationId查找ClientRegistration类
public interface ClientRegistrationRepository {
ClientRegistration findByRegistrationId(String var1);
}
InMemoryClientRegistrationRepository:使用内存保存客户端配置
public final class InMemoryClientRegistrationRepository implements ClientRegistrationRepository, Iterable<ClientRegistration> {
private final Map<String, ClientRegistration> registrations;
public InMemoryClientRegistrationRepository(ClientRegistration... registrations) {
this(Arrays.asList(registrations));
}
public InMemoryClientRegistrationRepository(List<ClientRegistration> registrations) {
this(createRegistrationsMap(registrations));
}
private static Map<String, ClientRegistration> createRegistrationsMap(List<ClientRegistration> registrations) {
Assert.notEmpty(registrations, "registrations cannot be empty");
return toUnmodifiableConcurrentMap(registrations);
}
private static Map<String, ClientRegistration> toUnmodifiableConcurrentMap(List<ClientRegistration> registrations) {
ConcurrentHashMap<String, ClientRegistration> result = new ConcurrentHashMap();
Iterator var2 = registrations.iterator();
while(var2.hasNext()) {
ClientRegistration registration = (ClientRegistration)var2.next();
if (result.containsKey(registration.getRegistrationId())) {
throw new IllegalStateException(String.format("Duplicate key %s", registration.getRegistrationId()));
}
result.put(registration.getRegistrationId(), registration);
}
return Collections.unmodifiableMap(result);
}
public InMemoryClientRegistrationRepository(Map<String, ClientRegistration> registrations) {
Assert.notNull(registrations, "registrations cannot be null");
this.registrations = registrations;
}
public ClientRegistration findByRegistrationId(String registrationId) {
Assert.hasText(registrationId, "registrationId cannot be empty");
return (ClientRegistration)this.registrations.get(registrationId);
}
public Iterator<ClientRegistration> iterator() {
return this.registrations.values().iterator();
}
}
OAuth2WebSecurityConfiguration:oauth2客户端安全配置
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnBean({ClientRegistrationRepository.class})
class OAuth2WebSecurityConfiguration {
OAuth2WebSecurityConfiguration() {
}
@Bean
@ConditionalOnMissingBean
OAuth2AuthorizedClientService authorizedClientService(ClientRegistrationRepository clientRegistrationRepository) {
return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
}//不存在 OAuth2AuthorizedClientService,则创建该类
@Bean
@ConditionalOnMissingBean
OAuth2AuthorizedClientRepository authorizedClientRepository(OAuth2AuthorizedClientService authorizedClientService) {
return new AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService);
}//不存在授权客户端,则创建AuthenticatedPrincipalOAuth2AuthorizedClientRepository
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnMissingBean({WebSecurityConfigurerAdapter.class})
static class OAuth2WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
OAuth2WebSecurityConfigurerAdapter() {
}
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> {
((AuthorizedUrl)requests.anyRequest()).authenticated();
});
http.oauth2Login(Customizer.withDefaults());
http.oauth2Client();
}//配置默认的安全策略
}
}
OAuth2AuthorizedClientService:授权客户端操作接口
public interface OAuth2AuthorizedClientService {
<T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String var1, String var2); //加载授权客户端
void saveAuthorizedClient(OAuth2AuthorizedClient var1, Authentication var2); //保存授权客户端
void removeAuthorizedClient(String var1, String var2); //删除授权客户端
}
InMemoryOAuth2AuthorizedClientService:授权客户端操作类
public final class InMemoryOAuth2AuthorizedClientService implements OAuth2AuthorizedClientService {
private final Map<OAuth2AuthorizedClientId, OAuth2AuthorizedClient> authorizedClients; //保存授权客户端
private final ClientRegistrationRepository clientRegistrationRepository;
public InMemoryOAuth2AuthorizedClientService(ClientRegistrationRepository clientRegistrationRepository) {
Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
this.clientRegistrationRepository = clientRegistrationRepository;
this.authorizedClients = new ConcurrentHashMap();
}
public InMemoryOAuth2AuthorizedClientService(ClientRegistrationRepository clientRegistrationRepository, Map<OAuth2AuthorizedClientId, OAuth2AuthorizedClient> authorizedClients) {
Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null");
Assert.notEmpty(authorizedClients, "authorizedClients cannot be empty");
this.clientRegistrationRepository = clientRegistrationRepository;
this.authorizedClients = new ConcurrentHashMap(authorizedClients);
}
public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String clientRegistrationId, String principalName) {
Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
Assert.hasText(principalName, "principalName cannot be empty");
ClientRegistration registration = this.clientRegistrationRepository.findByRegistrationId(clientRegistrationId);
return registration == null ? null : (OAuth2AuthorizedClient)this.authorizedClients.get(new OAuth2AuthorizedClientId(clientRegistrationId, principalName));
}
public void saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal) {
Assert.notNull(authorizedClient, "authorizedClient cannot be null");
Assert.notNull(principal, "principal cannot be null");
this.authorizedClients.put(new OAuth2AuthorizedClientId(authorizedClient.getClientRegistration().getRegistrationId(), principal.getName()), authorizedClient);
}
public void removeAuthorizedClient(String clientRegistrationId, String principalName) {
Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
Assert.hasText(principalName, "principalName cannot be empty");
ClientRegistration registration = this.clientRegistrationRepository.findByRegistrationId(clientRegistrationId);
if (registration != null) {
this.authorizedClients.remove(new OAuth2AuthorizedClientId(clientRegistrationId, principalName));
}
}
}
OAuth2AuthorizedClientId:Map<OAuth2AuthorizedClientId, OAuth2AuthorizedClient> authorizedClients中的key
public final class OAuth2AuthorizedClientId implements Serializable {
private static final long serialVersionUID = 530L;
private final String clientRegistrationId;
private final String principalName;
public OAuth2AuthorizedClientId(String clientRegistrationId, String principalName) {
public boolean equals(Object obj) {
public int hashCode() {
OAuth2AuthorizedClient:oauth2授权客户端
public class OAuth2AuthorizedClient implements Serializable {
private static final long serialVersionUID = 530L;
private final ClientRegistration clientRegistration;
private final String principalName;
private final OAuth2AccessToken accessToken;
private final OAuth2RefreshToken refreshToken;
public OAuth2AuthorizedClient(ClientRegistration clientRegistration, String principalName, OAuth2AccessToken accessToken) {
public OAuth2AuthorizedClient(ClientRegistration clientRegistration, String principalName, OAuth2AccessToken accessToken, @Nullable OAuth2RefreshToken refreshToken) {
public ClientRegistration getClientRegistration() { //获取客户端配置类
public String getPrincipalName() { //获取认证用户名称
public OAuth2AccessToken getAccessToken() { //获取access token
@Nullable
public OAuth2RefreshToken getRefreshToken() {
ClientRegistration:客户端类
public final class ClientRegistration implements Serializable {
private static final long serialVersionUID = 530L;
private String registrationId;
private String clientId;
private String clientSecret;
private ClientAuthenticationMethod clientAuthenticationMethod;
private AuthorizationGrantType authorizationGrantType;
private String redirectUriTemplate;
private Set<String> scopes;
private ClientRegistration.ProviderDetails providerDetails;
private String clientName;
private ClientRegistration() {
this.clientAuthenticationMethod = ClientAuthenticationMethod.BASIC;
this.scopes = Collections.emptySet();
this.providerDetails = new ClientRegistration.ProviderDetails();
}
public String getRegistrationId() {
public String getClientId() {
public String getClientSecret() {
public ClientAuthenticationMethod getClientAuthenticationMethod() {
public AuthorizationGrantType getAuthorizationGrantType() {
public String getRedirectUriTemplate() {
public Set<String> getScopes() {
public ClientRegistration.ProviderDetails getProviderDetails() {
public String getClientName() {
public String toString() {
public static ClientRegistration.Builder withRegistrationId(String registrationId) {
Assert.hasText(registrationId, "registrationId cannot be empty");
return new ClientRegistration.Builder(registrationId);
}
public static ClientRegistration.Builder withClientRegistration(ClientRegistration clientRegistration) {
Assert.notNull(clientRegistration, "clientRegistration cannot be null");
return new ClientRegistration.Builder(clientRegistration);
}
*****************
内部类:ClientRegistration.Builder
public static class Builder implements Serializable {
private static final long serialVersionUID = 530L;
private String registrationId;
private String clientId;
private String clientSecret;
private ClientAuthenticationMethod clientAuthenticationMethod;
private AuthorizationGrantType authorizationGrantType;
private String redirectUriTemplate;
private Set<String> scopes;
private String authorizationUri;
private String tokenUri;
private String userInfoUri;
private AuthenticationMethod userInfoAuthenticationMethod;
private String userNameAttributeName;
private String jwkSetUri;
private Map<String, Object> configurationMetadata;
private String clientName;
private Builder(String registrationId) {
this.clientAuthenticationMethod = ClientAuthenticationMethod.BASIC;
this.userInfoAuthenticationMethod = AuthenticationMethod.HEADER;
this.configurationMetadata = Collections.emptyMap();
this.registrationId = registrationId;
}
private Builder(ClientRegistration clientRegistration) {
public ClientRegistration.Builder registrationId(String registrationId) {
public ClientRegistration.Builder clientId(String clientId) {
public ClientRegistration.Builder clientSecret(String clientSecret) {
public ClientRegistration.Builder clientAuthenticationMethod(ClientAuthenticationMethod clientAuthenticationMethod) {
public ClientRegistration.Builder authorizationGrantType(AuthorizationGrantType authorizationGrantType) {
public ClientRegistration.Builder redirectUriTemplate(String redirectUriTemplate) {
public ClientRegistration.Builder scope(String... scope) {
public ClientRegistration.Builder scope(Collection<String> scope) {
public ClientRegistration.Builder authorizationUri(String authorizationUri) {
public ClientRegistration.Builder tokenUri(String tokenUri) {
public ClientRegistration.Builder userInfoUri(String userInfoUri) {
public ClientRegistration.Builder userInfoAuthenticationMethod(AuthenticationMethod userInfoAuthenticationMethod) {
public ClientRegistration.Builder userNameAttributeName(String userNameAttributeName) {
public ClientRegistration.Builder jwkSetUri(String jwkSetUri) {
public ClientRegistration.Builder providerConfigurationMetadata(Map<String, Object> configurationMetadata) {
public ClientRegistration.Builder clientName(String clientName) {
public ClientRegistration build() {
private ClientRegistration create() {
private void validateAuthorizationCodeGrantType() {
private void validateImplicitGrantType() {
private void validatePasswordGrantType() {
private void validateScopes() {
private static boolean validateScope(String scope) {
*****************
内部类:ClientRegistration.ProviderDetails
public class ProviderDetails implements Serializable {
private static final long serialVersionUID = 530L;
private String authorizationUri;
private String tokenUri;
private ClientRegistration.ProviderDetails.UserInfoEndpoint userInfoEndpoint;
private String jwkSetUri;
private Map<String, Object> configurationMetadata;
private ProviderDetails() {
this.userInfoEndpoint = new ClientRegistration.ProviderDetails.UserInfoEndpoint();
this.configurationMetadata = Collections.emptyMap();
}
public String getAuthorizationUri() {
public String getTokenUri() {
public ClientRegistration.ProviderDetails.UserInfoEndpoint getUserInfoEndpoint() {
public String getJwkSetUri() {
public Map<String, Object> getConfigurationMetadata() {
*****************
内部类:ClientRegistration.ProviderDetails.UserInfoEndpoint
public class UserInfoEndpoint implements Serializable {
private static final long serialVersionUID = 530L;
private String uri;
private AuthenticationMethod authenticationMethod;
private String userNameAttributeName;
private UserInfoEndpoint() {
this.authenticationMethod = AuthenticationMethod.HEADER;
}
public String getUri() {
public AuthenticationMethod getAuthenticationMethod() {
public String getUserNameAttributeName() {
OAuth2AuthorizedClientRepository:授权客户端操作接口
public interface OAuth2AuthorizedClientRepository {
<T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String var1, Authentication var2, HttpServletRequest var3);
void saveAuthorizedClient(OAuth2AuthorizedClient var1, Authentication var2, HttpServletRequest var3, HttpServletResponse var4);
void removeAuthorizedClient(String var1, Authentication var2, HttpServletRequest var3, HttpServletResponse var4);
}
AuthenticatedPrincipalOAuth2AuthorizedClientRepository:OAuth2AuthorizedClientRepository接口实现类
public final class AuthenticatedPrincipalOAuth2AuthorizedClientRepository implements OAuth2AuthorizedClientRepository {
private final AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
private final OAuth2AuthorizedClientService authorizedClientService;
//内部调用authorizedClientService方法
private OAuth2AuthorizedClientRepository anonymousAuthorizedClientRepository = new HttpSessionOAuth2AuthorizedClientRepository();
public AuthenticatedPrincipalOAuth2AuthorizedClientRepository(OAuth2AuthorizedClientService authorizedClientService) {
Assert.notNull(authorizedClientService, "authorizedClientService cannot be null");
this.authorizedClientService = authorizedClientService;
}
public void setAnonymousAuthorizedClientRepository(OAuth2AuthorizedClientRepository anonymousAuthorizedClientRepository) {
Assert.notNull(anonymousAuthorizedClientRepository, "anonymousAuthorizedClientRepository cannot be null");
this.anonymousAuthorizedClientRepository = anonymousAuthorizedClientRepository;
}
public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String clientRegistrationId, Authentication principal, HttpServletRequest request) {
return this.isPrincipalAuthenticated(principal) ? this.authorizedClientService.loadAuthorizedClient(clientRegistrationId, principal.getName()) : this.anonymousAuthorizedClientRepository.loadAuthorizedClient(clientRegistrationId, principal, request);
//通过认证后,调用authotizedClientService的loadAuthorizedClient加载授权客户端
}
public void saveAuthorizedClient(OAuth2AuthorizedClient authorizedClient, Authentication principal, HttpServletRequest request, HttpServletResponse response) {
if (this.isPrincipalAuthenticated(principal)) {
this.authorizedClientService.saveAuthorizedClient(authorizedClient, principal);
//通过认证后,调用authoriedClientService的saveAuthorizedClient保存授权客户端
} else {
this.anonymousAuthorizedClientRepository.saveAuthorizedClient(authorizedClient, principal, request, response);
}
}
public void removeAuthorizedClient(String clientRegistrationId, Authentication principal, HttpServletRequest request, HttpServletResponse response) {
if (this.isPrincipalAuthenticated(principal)) {
this.authorizedClientService.removeAuthorizedClient(clientRegistrationId, principal.getName());
//通过认证后,调用authoriedClientService的removeAuthorizedClient删除授权客户端
} else {
this.anonymousAuthorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal, request, response);
}
}
private boolean isPrincipalAuthenticated(Authentication authentication) {
return authentication != null && !this.authenticationTrustResolver.isAnonymous(authentication) && authentication.isAuthenticated();
}
}
CommonOAuth2Provider:默认提供的三方客户端配置,google、github、facebook、okta
public enum CommonOAuth2Provider {
GOOGLE {
public Builder getBuilder(String registrationId) {
Builder builder = this.getBuilder(registrationId, ClientAuthenticationMethod.BASIC, "{baseUrl}/{action}/oauth2/code/{registrationId}");
builder.scope(new String[]{"openid", "profile", "email"});
builder.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth");
builder.tokenUri("https://www.googleapis.com/oauth2/v4/token");
builder.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs");
builder.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo");
builder.userNameAttributeName("sub");
builder.clientName("Google");
return builder;
}
},
GITHUB {
public Builder getBuilder(String registrationId) {
Builder builder = this.getBuilder(registrationId, ClientAuthenticationMethod.BASIC, "{baseUrl}/{action}/oauth2/code/{registrationId}");
builder.scope(new String[]{"read:user"});
builder.authorizationUri("https://github.com/login/oauth/authorize");
builder.tokenUri("https://github.com/login/oauth/access_token");
builder.userInfoUri("https://api.github.com/user");
builder.userNameAttributeName("id");
builder.clientName("GitHub");
return builder;
}
},
FACEBOOK {
public Builder getBuilder(String registrationId) {
Builder builder = this.getBuilder(registrationId, ClientAuthenticationMethod.POST, "{baseUrl}/{action}/oauth2/code/{registrationId}");
builder.scope(new String[]{"public_profile", "email"});
builder.authorizationUri("https://www.facebook.com/v2.8/dialog/oauth");
builder.tokenUri("https://graph.facebook.com/v2.8/oauth/access_token");
builder.userInfoUri("https://graph.facebook.com/me?fields=id,name,email");
builder.userNameAttributeName("id");
builder.clientName("Facebook");
return builder;
}
},
OKTA {
public Builder getBuilder(String registrationId) {
Builder builder = this.getBuilder(registrationId, ClientAuthenticationMethod.BASIC, "{baseUrl}/{action}/oauth2/code/{registrationId}");
builder.scope(new String[]{"openid", "profile", "email"});
builder.userNameAttributeName("sub");
builder.clientName("Okta");
return builder;
}
};
private static final String DEFAULT_REDIRECT_URL = "{baseUrl}/{action}/oauth2/code/{registrationId}";
private CommonOAuth2Provider() {
}
protected final Builder getBuilder(String registrationId, ClientAuthenticationMethod method, String redirectUri) {
Builder builder = ClientRegistration.withRegistrationId(registrationId);
builder.clientAuthenticationMethod(method);
builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
builder.redirectUriTemplate(redirectUri);
return builder;
}
public abstract Builder getBuilder(String var1);
}
**************************
安全配置类
HttpSecurity:安全配置
public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity> implements SecurityBuilder<DefaultSecurityFilterChain>, HttpSecurityBuilder<HttpSecurity> {
***************
OAuth2Login 相关配置
public OAuth2LoginConfigurer<HttpSecurity> oauth2Login() throws Exception {
return (OAuth2LoginConfigurer)this.getOrApply(new OAuth2LoginConfigurer());
}
public HttpSecurity oauth2Login(Customizer<OAuth2LoginConfigurer<HttpSecurity>> oauth2LoginCustomizer) throws Exception {
oauth2LoginCustomizer.customize(this.getOrApply(new OAuth2LoginConfigurer()));
return this;
}
OAuth2LoginConfigurer
public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> extends AbstractAuthenticationFilterConfigurer<B, OAuth2LoginConfigurer<B>, OAuth2LoginAuthenticationFilter> {
private final OAuth2LoginConfigurer<B>.AuthorizationEndpointConfig authorizationEndpointConfig = new OAuth2LoginConfigurer.AuthorizationEndpointConfig();
private final OAuth2LoginConfigurer<B>.TokenEndpointConfig tokenEndpointConfig = new OAuth2LoginConfigurer.TokenEndpointConfig();
private final OAuth2LoginConfigurer<B>.RedirectionEndpointConfig redirectionEndpointConfig = new OAuth2LoginConfigurer.RedirectionEndpointConfig();
private final OAuth2LoginConfigurer<B>.UserInfoEndpointConfig userInfoEndpointConfig = new OAuth2LoginConfigurer.UserInfoEndpointConfig();
private String loginPage;
private String loginProcessingUrl = "/login/oauth2/code/*"; //获得授权码code后的回调路径
public OAuth2LoginConfigurer() {
}
public OAuth2LoginConfigurer<B> clientRegistrationRepository(ClientRegistrationRepository clientRegistrationRepository) {
public OAuth2LoginConfigurer<B> authorizedClientRepository(OAuth2AuthorizedClientRepository authorizedClientRepository) {
public OAuth2LoginConfigurer<B> authorizedClientService(OAuth2AuthorizedClientService authorizedClientService) {
public OAuth2LoginConfigurer<B> loginPage(String loginPage) {
public OAuth2LoginConfigurer<B> loginProcessingUrl(String loginProcessingUrl) {
*************
authorizationEndpoint:请求获取授权码相关操作
public OAuth2LoginConfigurer<B>.AuthorizationEndpointConfig authorizationEndpoint() {
public OAuth2LoginConfigurer<B> authorizationEndpoint(Customizer<OAuth2LoginConfigurer<B>.AuthorizationEndpointConfig> authorizationEndpointCustomizer) {
*************
tokenEndpoint:token相关操作
public OAuth2LoginConfigurer<B>.TokenEndpointConfig tokenEndpoint() {
public OAuth2LoginConfigurer<B> tokenEndpoint(Customizer<OAuth2LoginConfigurer<B>.TokenEndpointConfig> tokenEndpointCustomizer) {
*************
redirectionEndpoint:获取授权码code后的回调操作
public OAuth2LoginConfigurer<B>.RedirectionEndpointConfig redirectionEndpoint() {
public OAuth2LoginConfigurer<B> redirectionEndpoint(Customizer<OAuth2LoginConfigurer<B>.RedirectionEndpointConfig> redirectionEndpointCustomizer) {
*************
userInfoEndpoint:用户信息操作(用户权限、自定义用户类)
public OAuth2LoginConfigurer<B>.UserInfoEndpointConfig userInfoEndpoint() {
public OAuth2LoginConfigurer<B> userInfoEndpoint(Customizer<OAuth2LoginConfigurer<B>.UserInfoEndpointConfig> userInfoEndpointCustomizer) {
public void init(B http) throws Exception { //初始化操作
OAuth2LoginAuthenticationFilter authenticationFilter = new OAuth2LoginAuthenticationFilter(OAuth2ClientConfigurerUtils.getClientRegistrationRepository((HttpSecurityBuilder)this.getBuilder()), OAuth2ClientConfigurerUtils.getAuthorizedClientRepository((HttpSecurityBuilder)this.getBuilder()), this.loginProcessingUrl);
this.setAuthenticationFilter(authenticationFilter); //设置登录认证过滤器
super.loginProcessingUrl(this.loginProcessingUrl); //设置登陆处理路径,默认为:/login/oauth2/code/*
if (this.loginPage != null) {
super.loginPage(this.loginPage);
super.init(http);
} else {
Map<String, String> loginUrlToClientName = this.getLoginLinks();
if (loginUrlToClientName.size() == 1) {
this.updateAuthenticationDefaults();
this.updateAccessDefaults(http);
String providerLoginPage = (String)loginUrlToClientName.keySet().iterator().next();
this.registerAuthenticationEntryPoint(http, this.getLoginEntryPoint(http, providerLoginPage));
} else {
super.init(http);
}
} //登陆页面路径设置,默认为:/login
OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient = this.tokenEndpointConfig.accessTokenResponseClient;
if (accessTokenResponseClient == null) {
accessTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient();
}
OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService = this.getOAuth2UserService();
OAuth2LoginAuthenticationProvider oauth2LoginAuthenticationProvider = new OAuth2LoginAuthenticationProvider((OAuth2AccessTokenResponseClient)accessTokenResponseClient, oauth2UserService);
GrantedAuthoritiesMapper userAuthoritiesMapper = this.getGrantedAuthoritiesMapper();
if (userAuthoritiesMapper != null) {
oauth2LoginAuthenticationProvider.setAuthoritiesMapper(userAuthoritiesMapper);
}
http.authenticationProvider((AuthenticationProvider)this.postProcess(oauth2LoginAuthenticationProvider));
boolean oidcAuthenticationProviderEnabled = ClassUtils.isPresent("org.springframework.security.oauth2.jwt.JwtDecoder", this.getClass().getClassLoader());
if (oidcAuthenticationProviderEnabled) {
OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService = this.getOidcUserService();
OidcAuthorizationCodeAuthenticationProvider oidcAuthorizationCodeAuthenticationProvider = new OidcAuthorizationCodeAuthenticationProvider((OAuth2AccessTokenResponseClient)accessTokenResponseClient, oidcUserService);
JwtDecoderFactory<ClientRegistration> jwtDecoderFactory = this.getJwtDecoderFactoryBean();
if (jwtDecoderFactory != null) {
oidcAuthorizationCodeAuthenticationProvider.setJwtDecoderFactory(jwtDecoderFactory);
}
if (userAuthoritiesMapper != null) {
oidcAuthorizationCodeAuthenticationProvider.setAuthoritiesMapper(userAuthoritiesMapper);
}
http.authenticationProvider((AuthenticationProvider)this.postProcess(oidcAuthorizationCodeAuthenticationProvider));
} else {
http.authenticationProvider(new OAuth2LoginConfigurer.OidcAuthenticationRequestChecker());
}
this.initDefaultLoginFilter(http);
}
public void configure(B http) throws Exception {
OAuth2AuthorizationRequestRedirectFilter authorizationRequestFilter;
if (this.authorizationEndpointConfig.authorizationRequestResolver != null) {
authorizationRequestFilter = new OAuth2AuthorizationRequestRedirectFilter(this.authorizationEndpointConfig.authorizationRequestResolver);
} else {
String authorizationRequestBaseUri = this.authorizationEndpointConfig.authorizationRequestBaseUri;
if (authorizationRequestBaseUri == null) {
authorizationRequestBaseUri = "/oauth2/authorization";
}
authorizationRequestFilter = new OAuth2AuthorizationRequestRedirectFilter(OAuth2ClientConfigurerUtils.getClientRegistrationRepository((HttpSecurityBuilder)this.getBuilder()), authorizationRequestBaseUri);
}
if (this.authorizationEndpointConfig.authorizationRequestRepository != null) {
authorizationRequestFilter.setAuthorizationRequestRepository(this.authorizationEndpointConfig.authorizationRequestRepository);
}
RequestCache requestCache = (RequestCache)http.getSharedObject(RequestCache.class);
if (requestCache != null) {
authorizationRequestFilter.setRequestCache(requestCache);
}
http.addFilter((Filter)this.postProcess(authorizationRequestFilter));
OAuth2LoginAuthenticationFilter authenticationFilter = (OAuth2LoginAuthenticationFilter)this.getAuthenticationFilter();
if (this.redirectionEndpointConfig.authorizationResponseBaseUri != null) {
authenticationFilter.setFilterProcessesUrl(this.redirectionEndpointConfig.authorizationResponseBaseUri);
}
if (this.authorizationEndpointConfig.authorizationRequestRepository != null) {
authenticationFilter.setAuthorizationRequestRepository(this.authorizationEndpointConfig.authorizationRequestRepository);
}
super.configure(http);
}
protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) {
private JwtDecoderFactory<ClientRegistration> getJwtDecoderFactoryBean() {
private GrantedAuthoritiesMapper getGrantedAuthoritiesMapper() {
private GrantedAuthoritiesMapper getGrantedAuthoritiesMapperBean() {
private OAuth2UserService<OidcUserRequest, OidcUser> getOidcUserService() {
//返回OidcUserService对象
if (this.userInfoEndpointConfig.oidcUserService != null) {
return this.userInfoEndpointConfig.oidcUserService;
} else {
ResolvableType type = ResolvableType.forClassWithGenerics(OAuth2UserService.class, new Class[]{OidcUserRequest.class, OidcUser.class});
OAuth2UserService<OidcUserRequest, OidcUser> bean = (OAuth2UserService)this.getBeanOrNull(type);
return (OAuth2UserService)(bean == null ? new OidcUserService() : bean);
}
}
private OAuth2UserService<OAuth2UserRequest, OAuth2User> getOAuth2UserService() {
if (this.userInfoEndpointConfig.userService != null) {
//如果设置了userService,直接返回userService对象
return this.userInfoEndpointConfig.userService;
} else {
ResolvableType type = ResolvableType.forClassWithGenerics(OAuth2UserService.class, new Class[]{OAuth2UserRequest.class, OAuth2User.class});
OAuth2UserService<OAuth2UserRequest, OAuth2User> bean = (OAuth2UserService)this.getBeanOrNull(type);
if (bean == null) {
if (!this.userInfoEndpointConfig.customUserTypes.isEmpty()) {
//如果userInfoEndpointConfig中customUserTypes不为空,返回代理对象DelegatingOAuth2UserService
List<OAuth2UserService<OAuth2UserRequest, OAuth2User>> userServices = new ArrayList();
userServices.add(new CustomUserTypesOAuth2UserService(this.userInfoEndpointConfig.customUserTypes));
userServices.add(new DefaultOAuth2UserService());
return new DelegatingOAuth2UserService(userServices);
} else {
//如果为空,直接返回DefaultOAuth2UserService对象
return new DefaultOAuth2UserService();
}
} else {
return bean;
}
}
}
private <T> T getBeanOrNull(ResolvableType type) {
private void initDefaultLoginFilter(B http) { //生成默认的登陆页面
DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = (DefaultLoginPageGeneratingFilter)http.getSharedObject(DefaultLoginPageGeneratingFilter.class);
if (loginPageGeneratingFilter != null && !this.isCustomLoginPage()) {
loginPageGeneratingFilter.setOauth2LoginEnabled(true);
loginPageGeneratingFilter.setOauth2AuthenticationUrlToClientName(this.getLoginLinks());
loginPageGeneratingFilter.setLoginPageUrl(this.getLoginPage());
loginPageGeneratingFilter.setFailureUrl(this.getFailureUrl());
}
}
private Map<String, String> getLoginLinks() { //授权认证的uri地址
Iterable<ClientRegistration> clientRegistrations = null;
ClientRegistrationRepository clientRegistrationRepository = OAuth2ClientConfigurerUtils.getClientRegistrationRepository((HttpSecurityBuilder)this.getBuilder());
ResolvableType type = ResolvableType.forInstance(clientRegistrationRepository).as(Iterable.class);
if (type != ResolvableType.NONE && ClientRegistration.class.isAssignableFrom(type.resolveGenerics()[0])) {
clientRegistrations = (Iterable)clientRegistrationRepository;
}
if (clientRegistrations == null) {
return Collections.emptyMap();
} else {
String authorizationRequestBaseUri = this.authorizationEndpointConfig.authorizationRequestBaseUri != null ? this.authorizationEndpointConfig.authorizationRequestBaseUri : "/oauth2/authorization";
Map<String, String> loginUrlToClientName = new HashMap();
clientRegistrations.forEach((registration) -> {
String var10000 = (String)loginUrlToClientName.put(authorizationRequestBaseUri + "/" + registration.getRegistrationId(), registration.getClientName());
}); //授权请求默认为:/oauth2/authorization + registration.getRegistrationId()
return loginUrlToClientName;
}
}
private AuthenticationEntryPoint getLoginEntryPoint(B http, String providerLoginPage) {
***************
内部类:OAuth2LoginConfigurer.OidcAuthenticationRequestChecker
private static class OidcAuthenticationRequestChecker implements AuthenticationProvider {
private OidcAuthenticationRequestChecker() {
}
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
public boolean supports(Class<?> authentication) {
***************
内部类:OAuth2LoginConfigurer.UserInfoEndpointConfig
public class UserInfoEndpointConfig {
private OAuth2UserService<OAuth2UserRequest, OAuth2User> userService;
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
private Map<String, Class<? extends OAuth2User>> customUserTypes;
private UserInfoEndpointConfig() {
this.customUserTypes = new HashMap();
}
public OAuth2LoginConfigurer<B>.UserInfoEndpointConfig userService(OAuth2UserService<OAuth2UserRequest, OAuth2User> userService) {
//设置OAuth2UserService,通过OAuth2UserRequest请求获取user
public OAuth2LoginConfigurer<B>.UserInfoEndpointConfig oidcUserService(OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService) {
//设置OAuth2UserService,通过OidcUserRequest请求获取OidcUser
public OAuth2LoginConfigurer<B>.UserInfoEndpointConfig customUserType(Class<? extends OAuth2User> customUserType, String clientRegistrationId) {
//设置用户类型OAuth2User
public OAuth2LoginConfigurer<B>.UserInfoEndpointConfig userAuthoritiesMapper(GrantedAuthoritiesMapper userAuthoritiesMapper) {
//设置用户权限
public OAuth2LoginConfigurer<B> and() {
***************
内部类:OAuth2LoginConfigurer.RedirectionEndpointConfig
public class RedirectionEndpointConfig {
private String authorizationResponseBaseUri;
private RedirectionEndpointConfig() {
}
public OAuth2LoginConfigurer<B>.RedirectionEndpointConfig baseUri(String authorizationResponseBaseUri) {
//获取授权码code后,回调的baseUri
public OAuth2LoginConfigurer<B> and() {
***************
内部类:OAuth2LoginConfigurer.TokenEndpointConfig
public class TokenEndpointConfig {
private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient;
private TokenEndpointConfig() {
}
public OAuth2LoginConfigurer<B>.TokenEndpointConfig accessTokenResponseClient(OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient) {
//设置OAuth2AccessTokenResponseClient,通过该客户端获取token
public OAuth2LoginConfigurer<B> and() {
***************
内部类:OAuth2LoginConfigurer.AuthorizationEndpointConfig
public class AuthorizationEndpointConfig {
private String authorizationRequestBaseUri;
private OAuth2AuthorizationRequestResolver authorizationRequestResolver;
private AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository;
private AuthorizationEndpointConfig() {
}
public OAuth2LoginConfigurer<B>.AuthorizationEndpointConfig baseUri(String authorizationRequestBaseUri) {
//设置授权请求的baseUri,如果不设置,默认为:/oauth2/authorization
public OAuth2LoginConfigurer<B>.AuthorizationEndpointConfig authorizationRequestResolver(OAuth2AuthorizationRequestResolver authorizationRequestResolver) {
//设置授权请求解析类,将HttpServletRequest转换为OAuth2AuthorizationRequest
public OAuth2LoginConfigurer<B>.AuthorizationEndpointConfig authorizationRequestRepository(AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
//设置授权请求操作类,加载、保存、删除授权请求
public OAuth2LoginConfigurer<B> and() {
UserService:加载用户
@FunctionalInterface
public interface OAuth2UserService<R extends OAuth2UserRequest, U extends OAuth2User> {
U loadUser(R var1) throws OAuth2AuthenticationException;
}
DefaultOAuth2UserService:默认的用户加载类
public class DefaultOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private static final String MISSING_USER_INFO_URI_ERROR_CODE = "missing_user_info_uri";
private static final String MISSING_USER_NAME_ATTRIBUTE_ERROR_CODE = "missing_user_name_attribute";
private static final String INVALID_USER_INFO_RESPONSE_ERROR_CODE = "invalid_user_info_response";
private static final ParameterizedTypeReference<Map<String, Object>> PARAMETERIZED_RESPONSE_TYPE = new ParameterizedTypeReference<Map<String, Object>>() {
};
private Converter<OAuth2UserRequest, RequestEntity<?>> requestEntityConverter = new OAuth2UserRequestEntityConverter();
private RestOperations restOperations;
public DefaultOAuth2UserService() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
this.restOperations = restTemplate;
}
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
Assert.notNull(userRequest, "userRequest cannot be null");
if (!StringUtils.hasText(userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri())) {
OAuth2Error oauth2Error = new OAuth2Error("missing_user_info_uri", "Missing required UserInfo Uri in UserInfoEndpoint for Client Registration: " + userRequest.getClientRegistration().getRegistrationId(), (String)null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
} else {
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
if (!StringUtils.hasText(userNameAttributeName)) {
OAuth2Error oauth2Error = new OAuth2Error("missing_user_name_attribute", "Missing required \"user name\" attribute name in UserInfoEndpoint for Client Registration: " + userRequest.getClientRegistration().getRegistrationId(), (String)null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
} else {
RequestEntity request = (RequestEntity)this.requestEntityConverter.convert(userRequest);
ResponseEntity response;
OAuth2Error oauth2Error;
try {
response = this.restOperations.exchange(request, PARAMETERIZED_RESPONSE_TYPE);
} catch (OAuth2AuthorizationException var10) {
oauth2Error = var10.getError();
StringBuilder errorDetails = new StringBuilder();
errorDetails.append("Error details: [");
errorDetails.append("UserInfo Uri: ").append(userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri());
errorDetails.append(", Error Code: ").append(oauth2Error.getErrorCode());
if (oauth2Error.getDescription() != null) {
errorDetails.append(", Error Description: ").append(oauth2Error.getDescription());
}
errorDetails.append("]");
oauth2Error = new OAuth2Error("invalid_user_info_response", "An error occurred while attempting to retrieve the UserInfo Resource: " + errorDetails.toString(), (String)null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString(), var10);
} catch (RestClientException var11) {
oauth2Error = new OAuth2Error("invalid_user_info_response", "An error occurred while attempting to retrieve the UserInfo Resource: " + var11.getMessage(), (String)null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString(), var11);
}
Map<String, Object> userAttributes = (Map)response.getBody();
Set<GrantedAuthority> authorities = new LinkedHashSet();
authorities.add(new OAuth2UserAuthority(userAttributes)); //给用户添加默认的权限:ROLE_USER
OAuth2AccessToken token = userRequest.getAccessToken();
Iterator var8 = token.getScopes().iterator();
while(var8.hasNext()) {
String authority = (String)var8.next();
authorities.add(new SimpleGrantedAuthority("SCOPE_" + authority));
}//读取OAuth2AccessToken中的scopes,添加对应的权限,前缀为:SCOPE_
return new DefaultOAuth2User(authorities, userAttributes, userNameAttributeName);
}
}
}
public final void setRequestEntityConverter(Converter<OAuth2UserRequest, RequestEntity<?>> requestEntityConverter) {
Assert.notNull(requestEntityConverter, "requestEntityConverter cannot be null");
this.requestEntityConverter = requestEntityConverter;
}
public final void setRestOperations(RestOperations restOperations) {
Assert.notNull(restOperations, "restOperations cannot be null");
this.restOperations = restOperations;
}
}
OAuth2UserAuthority:用户权限类
public class OAuth2UserAuthority implements GrantedAuthority {
private static final long serialVersionUID = 520L;
private final String authority;
private final Map<String, Object> attributes;
public OAuth2UserAuthority(Map<String, Object> attributes) {
this("ROLE_USER", attributes);
}
public OAuth2UserAuthority(String authority, Map<String, Object> attributes) {
Assert.hasText(authority, "authority cannot be empty");
Assert.notEmpty(attributes, "attributes cannot be empty");
this.authority = authority;
this.attributes = Collections.unmodifiableMap(new LinkedHashMap(attributes));
}
public String getAuthority() {
public Map<String, Object> getAttributes() {
public boolean equals(Object obj) {
public int hashCode() {
public String toString() {
return this.getAuthority();
}
}
DefaultOAuth2User:默认用户类
public class DefaultOAuth2User implements OAuth2User, Serializable {
private static final long serialVersionUID = 520L;
private final Set<GrantedAuthority> authorities;
private final Map<String, Object> attributes;
private final String nameAttributeKey;
public DefaultOAuth2User(Collection<? extends GrantedAuthority> authorities, Map<String, Object> attributes, String nameAttributeKey) {
Assert.notEmpty(authorities, "authorities cannot be empty");
Assert.notEmpty(attributes, "attributes cannot be empty");
Assert.hasText(nameAttributeKey, "nameAttributeKey cannot be empty");
if (!attributes.containsKey(nameAttributeKey)) {
throw new IllegalArgumentException("Missing attribute '" + nameAttributeKey + "' in attributes");
} else {
this.authorities = Collections.unmodifiableSet(new LinkedHashSet(this.sortAuthorities(authorities)));
this.attributes = Collections.unmodifiableMap(new LinkedHashMap(attributes));
this.nameAttributeKey = nameAttributeKey;
}
}
public String getName() {
return this.getAttribute(this.nameAttributeKey).toString();
}
public Collection<? extends GrantedAuthority> getAuthorities() {
public Map<String, Object> getAttributes() {
private Set<GrantedAuthority> sortAuthorities(Collection<? extends GrantedAuthority> authorities) {
public boolean equals(Object obj) {
public int hashCode() {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Name: [");
sb.append(this.getName());
sb.append("], Granted Authorities: [");
sb.append(this.getAuthorities());
sb.append("], User Attributes: [");
sb.append(this.getAttributes());
sb.append("]");
return sb.toString();
}
}
**************************
相关过滤器
DefaultLoginPageGeneratingFilter:生成默认的登陆页面
public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
public static final String DEFAULT_LOGIN_PAGE_URL = "/login";
public static final String ERROR_PARAMETER_NAME = "error";
private String loginPageUrl;
private String logoutSuccessUrl;
private String failureUrl;
private boolean formLoginEnabled;
private boolean openIdEnabled;
private boolean oauth2LoginEnabled;
private boolean saml2LoginEnabled;
private String authenticationUrl;
private String usernameParameter;
private String passwordParameter;
private String rememberMeParameter;
private String openIDauthenticationUrl;
private String openIDusernameParameter;
private String openIDrememberMeParameter;
private Map<String, String> oauth2AuthenticationUrlToClientName;
private Map<String, String> saml2AuthenticationUrlToProviderName;
private Function<HttpServletRequest, Map<String, String>> resolveHiddenInputs = (request) -> {
return Collections.emptyMap();
};
public DefaultLoginPageGeneratingFilter() {
public DefaultLoginPageGeneratingFilter(AbstractAuthenticationProcessingFilter filter) {
public DefaultLoginPageGeneratingFilter(UsernamePasswordAuthenticationFilter authFilter, AbstractAuthenticationProcessingFilter openIDFilter) {
private void init(UsernamePasswordAuthenticationFilter authFilter, AbstractAuthenticationProcessingFilter openIDFilter) {
this.loginPageUrl = "/login";
this.logoutSuccessUrl = "/login?logout";
this.failureUrl = "/login?error";
if (authFilter != null) {
this.formLoginEnabled = true;
this.usernameParameter = authFilter.getUsernameParameter();
this.passwordParameter = authFilter.getPasswordParameter();
if (authFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
this.rememberMeParameter = ((AbstractRememberMeServices)authFilter.getRememberMeServices()).getParameter();
}
}
if (openIDFilter != null) {
this.openIdEnabled = true;
this.openIDusernameParameter = "openid_identifier";
if (openIDFilter.getRememberMeServices() instanceof AbstractRememberMeServices) {
this.openIDrememberMeParameter = ((AbstractRememberMeServices)openIDFilter.getRememberMeServices()).getParameter();
}
}
}
OAuth2AuthorizationRequestRedirectFilter:授权请求跳转过滤器
public class OAuth2AuthorizationRequestRedirectFilter extends OncePerRequestFilter {
public static final String DEFAULT_AUTHORIZATION_REQUEST_BASE_URI = "/oauth2/authorization";
private final ThrowableAnalyzer throwableAnalyzer;
private final RedirectStrategy authorizationRedirectStrategy;
private OAuth2AuthorizationRequestResolver authorizationRequestResolver;
private AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository;
private RequestCache requestCache;
public OAuth2AuthorizationRequestRedirectFilter(ClientRegistrationRepository clientRegistrationRepository) {
this(clientRegistrationRepository, "/oauth2/authorization");
}
public OAuth2AuthorizationRequestRedirectFilter(ClientRegistrationRepository clientRegistrationRepository, String authorizationRequestBaseUri) {
public OAuth2AuthorizationRequestRedirectFilter(OAuth2AuthorizationRequestResolver authorizationRequestResolver) {
OAuth2LoginAuthenticationFilter:获取授权码code后的认证过滤器
public class OAuth2LoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String DEFAULT_FILTER_PROCESSES_URI = "/login/oauth2/code/*";
private static final String AUTHORIZATION_REQUEST_NOT_FOUND_ERROR_CODE = "authorization_request_not_found";
private static final String CLIENT_REGISTRATION_NOT_FOUND_ERROR_CODE = "client_registration_not_found";
private ClientRegistrationRepository clientRegistrationRepository;
private OAuth2AuthorizedClientRepository authorizedClientRepository;
private AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository;
public OAuth2LoginAuthenticationFilter(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientService authorizedClientService) {
this(clientRegistrationRepository, authorizedClientService, "/login/oauth2/code/*");
}
public OAuth2LoginAuthenticationFilter(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientService authorizedClientService, String filterProcessesUrl) {
public OAuth2LoginAuthenticationFilter(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository, String filterProcessesUrl) {