自定义Spring Authorization Server登录页
一、鳴謝
首先要聲明一些感謝:
- 感謝官方文檔的缺失、反復造成我下面這條感謝
- 感謝那些胡說八道、顧彼失此的某DN文章,讓我在沖向坑里的道路上一往無前
廢話不多說,看劍!
本文來自:博客園-去哪里吃魚-自定義Spring Authorization Server登錄頁
二、版本信息
本文基于如下以來版本信息,官方代碼如有變動,請自行閱讀源碼解決問題。
友情提示:不要照抄某DN、AI內容,避免浪費生命。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
<version>3.3.10</version>
</dependency>
<!-- 上面的依賴引用的 spring-security-oauth2-authorization-server 版本,這里只做提示,不用引入 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-authorization-server</artifactId>
<version>1.3.5</version>
</dependency>
三、過濾器鏈介紹
使用 Spring Authorization Server 開發授權服務器,必然不可少要配置兩個 SecurityFilterChain過濾器鏈:
SpringSecurity的過濾器鏈- 授權服務的過濾器鏈
這兩條過濾器鏈不會沖突,但是要確保授權服務器的過濾器鏈在SpringSecurity鏈之前加載,在代碼當中可以使用@Order(0)注解來調整,注解中的整數參數越小,加載順序就越靠前
調整的目的是:
SpringSecurity的過濾器鏈默認所有請求都需要認證,把授權服務的過濾器鏈提前,可以避免如下默認授權相關請求不受SpringSecurity的過濾器鏈影響
- /oauth2/authorize
- /oauth2/token
- /oauth2/jwks
- /userinfo
- /login
- ...
如下基于 授權碼 模式進行開發,默認的,以 GET 方式請求的 /login 是跳轉到登錄頁,以 POST 方式請求的 /login 則是處理登錄請求,Spring 官方以硬編碼的形式提供了一個默認登錄頁,其中引用了bootstrap 樣式文件,鑒于一些總所周知的原因,這個樣式文件訪問不了,所以登錄頁加載會很慢。
此外,每個產品也會相應的設計具有自己產品風格特性的登錄頁,這讓自定義登錄頁成為了一個硬性需求。
如下為 只修改登錄頁 的處理過程,一些項目配置如下
- 應用 context-path 自定義為 'auth'
- 自定義登錄頁請求地址為: http://domain/auth/i/login
四、修改 SpringSecurity 配置
貼一段基于官方demo的修改后的配置代碼:
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/i/**","/login**").permitAll()
.anyRequest().authenticated()
)
.cors(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
.formLogin(form -> form.loginPage("/i/login").loginProcessingUrl("/login"));
return http.build();
}
現在來說一下注意事項:
- 登錄頁請求由
SpringSecurity的過濾器鏈處理,因為授權服務過濾器鏈沒有設置formLogin,它只處理相關接口 - 在配置
formLogin的時候,loginPage和loginProcessingUrl都需要配置,如果不配置loginProcessingUrl,它則會用loginPage的 url來處理登錄請求 - 除了登錄頁請求放開,登錄請求也要放開,交由授權服務過濾器鏈處理,在代碼中就是
requestMatchers("/i/**","/login**").permitAll()
五、修改 Spring Authorization Server 配置
同樣基于官方demo的修改后的配置:
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(withDefaults());
http.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint(domain + "/auth/i/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
.oauth2ResourceServer((resourceServer) -> resourceServer.jwt(Customizer.withDefaults()));
return http.build();
}
注意事項之在代碼 new LoginUrlAuthenticationEntryPoint(domain + "/auth/i/login") 中
domain變量僅在有需要的情況下使用,也可以不用- 構造函數中的地址,一定一定要與上一章節中的
loginPage地址相同,不要被xxxEntryPoint迷惑,這里就是指登錄頁地址!
六、其他
自定義授權確認頁面不在此篇幅范圍之內,這個版本當客戶端請求的 role 是一個值的時候不會出現授權確認頁面。
我解決這種自定義問題的思路:
研究 Spring Security 的配置方式,如:
SecurityBuilder,SecurityConfiger,從而找到自己出現問題所在的步驟,針對性的去調整
看到這里,希望對你有所幫助。
總結
以上是生活随笔為你收集整理的自定义Spring Authorization Server登录页的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Longest Univalue Pat
- 下一篇: 15.4K Star!Vercel官方出