①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳✕✓✔✖
认证
个人信息管理
系统管理
Spring 自带的 github 等登陆,但是追加自定义微信,需要写一部分代码。
今后会将微信登陆作为一个单独的包,打包。
这里兼用了github
与微信网页登陆两种形式。
spring:thymeleaf:cache: falsesecurity:oauth2:client:registration:github:client-id: cadd65bbbc65ab9111179client-secret: 62b27f0df2fcebb11118402wechat_open:client-id: wxa111aeclient-secret: a11111193redirect-uri: 'https://frp.redhtc.com/login/oauth2/code/wechat-open'
微信登陆的redirect-uri
做个特殊的制定,因为使用了nginx
做了跳转。
下面是一个完整的代码包,核心的地址在配置oAuth2LoginConfigurer
类。
@EnableWebSecuritypublic class SecurityConfiguration {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http, ClientRegistrationRepository clientRegistrationRepository, OAuth2AccessTokenResponseClient oAuth2AccessTokenResponseClient, OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver, OAuth2UserService oAuth2UserService) throws Exception {http.authorizeRequests((authorize) -> authorize// 这个必须添加不然返回:/login?logout会认为没有权限,然后直接给跳转到/login,这样参数就没有了。.antMatchers(HttpMethod.GET,"/login").permitAll().anyRequest().authenticated())//配置login.exceptionHandling(exceptionHandling->{exceptionHandling.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"));}).formLogin(withDefaults());// 添加第三方登陆接口OAuth2LoginConfigurer oAuth2LoginConfigurer=new OAuth2LoginConfigurer(clientRegistrationRepository,oAuth2AccessTokenResponseClient,oAuth2AuthorizationRequestResolver,oAuth2UserService);http.apply(oAuth2LoginConfigurer);return http.build();}@Beanpublic UserDetailsService userDetailsService() {UserDetails user = User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build();return new InMemoryUserDetailsManager(user);}}
在登陆页面下面添加两个链接:
常见的第三方登陆都会封装到代码中,自己需要扩展的地方很少。如果真需要扩展,可以自定义@Bean 来扩展下面 4 部分:
OAuth2AuthorizationRequestResolver
OAuth2AccessTokenResponseClient
OAuth2UserService
关于成功handler
,可以通过OAuth2LoginConfigurer.setSuccessHandler
来实现。
实际上,上面的三个代码都是通过代理来实现的,也可以这么来扩展:
@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http, ClientRegistrationRepository clientRegistrationRepository, OAuth2AccessTokenResponseClient oAuth2AccessTokenResponseClient, OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver, OAuth2UserService oAuth2UserService) throws Exception {//例如要扩展OAuth2UserService((DelegatingOAuth2UserService)oAuth2UserService).addOAuth2UserService(这里添加自己的逻辑类);// 添加第三方登陆接口OAuth2LoginConfigurer oAuth2LoginConfigurer=new OAuth2LoginConfigurer(clientRegistrationRepository,oAuth2AccessTokenResponseClient,oAuth2AuthorizationRequestResolver,oAuth2UserService);http.apply(oAuth2LoginConfigurer);return http.build();}
这里只分析 Spring 的代码,参考了文档:Spring 全家桶-Spring Security 之 OAuth2.0 认证
OAuth2ClientAutoConfiguration
处理配置文件的 bean,这个类包含了两个子类:
OAuth2ClientRegistrationRepositoryConfiguration
:用来加载第三方登陆的配置文件,返回InMemoryClientRegistrationRepository
OAuth2ClientPropertiesRegistrationAdapter
CommonOAuth2Provider
提供了google,github,facebook,OKTA
的处理方式并设置回调地址等OAuth2ClientProperties
属性维护类OAuth2WebSecurityConfiguration
: 用来返回 3 个内容:SecurityFilterChain OAuth2AuthorizedClientRepository OAuth2AuthorizedClientService
其中主要 Filter 的主要配置内容在OAuth2ClientConfigurer
类中。
入口
Filter | URI | 作用 |
---|---|---|
OAuth2AuthorizationRequestRedirectFilter | /oauth2/authorization/{registrationId} | 从客户端,跳转到 OAuth2 认证服务器的入口 |
OAuth2LoginAuthenticationFilter | /login/oauth2/code/{registrationId} | redirect-uri 的回调地址 |
这个类的主要工作:
//解析出OAuth2AuthorizationRequestOAuth2AuthorizationRequest authorizationRequest = this.authorizationRequestResolver.resolve(request);//保存OAuth2AuthorizationRequestthis.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest, request, response);//进行跳转this.authorizationRedirectStrategy.sendRedirect(request, response,authorizationRequest.getAuthorizationRequestUri());
OAuth2AuthorizationRequestRedirectFilter
相关的子类:
OAuth2AuthorizationRequest
一个用来存储 OAuth2 请求过程中数据的类。代码很简单,中间使用了几个工具:UriBuilder CollectionUtils StringUtils UriUtils
OAuth2AuthorizationRequestResolver
接口默认实现类是:
DefaultOAuth2AuthorizationRequestResolver
,请求 code 链接的转换器。为了便于外部扩展,这个类定义了一个
customer
插件Consumer<Builder> authorizationRequestCustomizer
,并通过setAuthorizationRequestCustomizer
方法来设置。
AuthorizationRequestRepository
接口用来保存
OAuth2AuthorizationRequest
的,主要的方法有:loadAuthorizationRequest saveAuthorizationRequest removeAuthorizationRequest
。默认的实现类是:HttpSessionOAuth2AuthorizationRequestRepository
- 默认会保存在 session,每次只能保存一个,如果要保存多个,可以用 state 作为 key,保存到一个 map 中。
可以参考到的类
* @see AbstractAuthenticationProcessingFilter* @see OAuth2LoginAuthenticationToken* @see OAuth2AuthenticationToken* @see OAuth2LoginAuthenticationProvider* @see OAuth2AuthorizationRequest* @see OAuth2AuthorizationResponse* @see AuthorizationRequestRepository* @see OAuth2AuthorizationRequestRedirectFilter* @see ClientRegistrationRepository* @see OAuth2AuthorizedClient* @see OAuth2AuthorizedClientRepository