SpringBoot從1.x升級到2.x后單點登陸SSO問題的解決方法

這篇文章主要介紹“Spring Boot 從1.x升級到 2.x 后 單點登陸SSO問題的解決方法”,在日常操作中,相信很多人在Spring Boot 從1.x升級到 2.x 后 單點登陸SSO問題的解決方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spring Boot 從1.x升級到 2.x 后 單點登陸SSO問題的解決方法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

創(chuàng)新互聯(lián)建站網站建設公司是一家服務多年做網站建設策劃設計制作的公司,為廣大用戶提供了成都網站設計、成都網站制作,成都網站設計,廣告投放平臺,成都做網站選創(chuàng)新互聯(lián)建站,貼合企業(yè)需求,高性價比,滿足客戶不同層次的需求一站式服務歡迎致電。

解決Spring Boot 從1.x升級到 2.x 后 單點登陸(SSO)問題

> ??在學習Spring Cloud 時,遇到了授權服務oauth 相關內容時,總是一知半解,因此決定先把Spring Security 、Spring Security Oauth3 等權限、認證相關的內容、原理及設計學習并整理一遍。本系列文章就是在學習的過程中加強印象和理解所撰寫的,如有侵權請告知。

> 項目環(huán)境: > - JDK1.8 > - Spring boot 2.x > - Spring Security 5.x

??前期基本上已經將 Spring Security相關的內容寫得差不多了,所以最近在整理Spring Sexurity Oauh3 相關的內容,但在進行到單點登陸(OSS)時,有一個問題一直困擾了我很久,由于網上有關于Spring Boot 1.x 升級到Spring Boot 2.x 后單點登陸相關的問題解決資料很少,特此在這里專門列一篇文章來描述升級過程中遇到的一些問題、問題表現(xiàn)現(xiàn)象以及我是如何解決這些問題的。

問題一: spring boot 2 中去除了@EnableOAuth3Sso ?

??首先很明確的告訴你,并沒有?。〉珵槭裁匆肓?spring-security-oauth3maven依賴 IDEA提示 @EnableOAuth3Sso 找不到呢? 首先我們找到官方Spring Boot 2.x 升級文檔,我們會發(fā)現(xiàn)其中有關于Oauth3 相關的介紹:

> OAuth 2.0 Support Functionality from the Spring Security OAuth project is being migrated to core Spring Security. OAuth 2.0 client support has already been added and additional features will be migrated in due course.

> If you depend on Spring Security OAuth features that have not yet been migrated you will need to add org.springframework.security.oauth:spring-security-oauth3 and configure things manually. If you only need OAuth 2.0 client support you can use the auto-configurationprovided by Spring Boot 2.0. We’re also continuing to support Spring Boot 1.5 so older applications can continue to use that until an upgrade path is provided.

?? 我們可以大致明白 官方 2.x 正在將 Spring Security OAuth項目的功能遷移到 Spring Security 中。 但最值得注意的是其中有這么一段話 If you only need OAuth 2.0 client support you can use the auto-configurationprovided by Spring Boot 2.0.(如果你想要在Spring Boot 2.0(及以上)版本中使用 Oauth3 客戶端 相關的功能 需要使用 auto-configuration)。

??根據這個提示,我們找到 官方 auto-configuration文檔 ,一進來 就告訴我們需要用到的最小maven依賴:

        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-security</artifactid>
        </dependency>
        <dependency>
            <groupid>org.springframework.security.oauth.boot</groupid>
            <artifactid>spring-security-oauth3-autoconfigure</artifactid>
            <version>2.1.7.RELEASE</version>
        </dependency>

??按照官方文檔配置成功引用到了@EnableOAuth3Sso ,至此,該問題得到解決!

問題二: 單點登陸授權過程中回調到客戶端卻提示401(未授權)問題 ?

####一、 SSO 客戶端相關配置

ClientSecurityConfig 配置
@Configuration
@EnableOAuth3Sso  // SSo自動配置引用
public class ClientSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
                .csrf().disable();
    }

}

這個配置是按照 官方 auto-configuration文檔  推薦的配置。

application.yml 配置
auth-server: http://localhost:9090 # authorization服務地址


security:
  oauth3:
    client:
      user-authorization-uri: ${auth-server}/oauth/authorize #請求認證的地址
      access-token-uri: ${auth-server}/oauth/token #請求令牌的地址
    resource:
      jwt:
        key-uri: ${auth-server}/oauth/token_key #解析jwt令牌所需要密鑰的地址,服務啟動時會調用 授權服務該接口獲取jwt key,所以務必保證授權服務正常
    sso:
      login-path: /login #指向登錄頁面的路徑,即OAuth3授權服務器觸發(fā)重定向到客戶端的路徑 ,默認為 /login
spring:
  profiles:
    active: client1

??由于我們要多客戶端單點測試,這里使用Spring boot 的多環(huán)境配置,這里有關授權服務的配置不在描述,以及默認搭建好了一個可用的授權服務(如果不清楚如何搭建Oauth3的授權服務和資源服務,可以關注我,后續(xù)會出相關文章)。

application-client1.yml 配置
    server:
      port: 8091
    
    security:
      oauth3:
        client:
          client-id: client1
          client-secret: 123456
測試接口
@RestController
@Slf4j
public class TestController {

    @GetMapping("/client/{clientId}")
    public String getClient(@PathVariable String clientId) {
        return clientId;
    }

}

?? 至此問我們完成了一個最基本的SSO客戶端,啟動項目。

####二、 問題描述及現(xiàn)象 ??瀏覽器上訪問測試接口 localhost:8091/client/1 ,跳轉到授權服務登陸界面,登陸成功后,跳轉回到客戶端的 /login 地址 (即 我們 配置的 spring.security.sso.login-path ),正常情況下會再次跳轉到 localhost:8091/client/1(這次已經是認證成功后訪問)。這整個流程就是Oauth3 的授權碼模式流程。但現(xiàn)在有這么一個問題,在授權服務回調到客戶端的 /login 地址時,瀏覽器顯示 HTTP ERROR 401, 如下圖: Spring Boot 從1.x升級到 2.x 后 單點登陸SSO問題的解決方法

??從圖中我們可以看到,授權服務成功的返回了授權碼,但由于我們客戶端存在問題,出現(xiàn) 401 ,導致整個授權碼模式流程中斷。 在看 官方 auto-configuration文檔  過程中,無意間發(fā)現(xiàn)

>Also note that since all endpoints are secure by default, this includes any default error handling endpoints, for example, the endpoint "/error". This means that if there is some problem during Single Sign On that requires the application to redirect to the "/error" page, then this can cause an infinite redirect between the identity provider and the receiving application. >First, think carefully about making an endpoint insecure as you may find that the behavior is simply evidence of a different problem. However, this behavior can be addressed by configuring the application to permit "/error":

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/error").permitAll()
                .anyRequest().authenticated();
    }
}

??大致意思就是:由于默認情況下所有端點都是安全的,因此這包括任何默認錯誤處理端點,例如端點“/ error”。這意味著如果單點登錄期間存在某些問題,需要應用程序重定向到“/ error”頁面,則這會導致身份提供程序和接收應用程序之間的無限重定向。

??根據這個提示,我開始DEBUG,果然正如文檔所說,單點登錄期間存在某些問題重定向到了/error,所以我們將 /error 配置成無權限訪問,重啟再次訪問測試接口,這次的錯誤界面提示就很明顯了: Spring Boot 從1.x升級到 2.x 后 單點登陸SSO問題的解決方法

??既然明顯的提示 Unauthorized 了,那我們就來一步一步的DEBUG 看看單點期間出現(xiàn)的問題點是什么。

####三、 問題排查及解決方案 ??從之前的現(xiàn)象描述我們可以知道問題點在授權碼回來后去調用獲取token這里出現(xiàn)問題了,那么根據源碼查看,獲取token這塊步驟在 OAuth3ClientAuthenticationProcessingFilter 過濾器內部,其關鍵代碼如下:

    @Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException, IOException, ServletException {

		OAuth3AccessToken accessToken;
		try {
			accessToken = restTemplate.getAccessToken();  // 1 調用授權服務獲取token 
		} catch (OAuth3Exception e) {
			BadCredentialsException bad = new BadCredentialsException("Could not obtain access token", e);
			publish(new OAuth3AuthenticationFailureEvent(bad));
			throw bad;			
		}
		try {
			OAuth3Authentication result = tokenServices.loadAuthentication(accessToken.getValue());  // 成功后從token中解析  OAuth3Authentication 信息
			if (authenticationDetailsSource!=null) {
				request.setAttribute(OAuth3AuthenticationDetails.ACCESS_TOKEN_VALUE, accessToken.getValue());
				request.setAttribute(OAuth3AuthenticationDetails.ACCESS_TOKEN_TYPE, accessToken.getTokenType());
				result.setDetails(authenticationDetailsSource.buildDetails(request));
			}
			publish(new AuthenticationSuccessEvent(result));
			return result;
		}
		catch (InvalidTokenException e) {
			BadCredentialsException bad = new BadCredentialsException("Could not obtain user details from token", e);
			publish(new OAuth3AuthenticationFailureEvent(bad));
			throw bad;			
		}

	}

??我們把斷點打到這里,Debug下,果然不出所料,在獲取token時異常了,異常信息為 : Possible CSRF detected - state parameter was required but no state could be found ,debug截圖如下: Spring Boot 從1.x升級到 2.x 后 單點登陸SSO問題的解決方法

??查閱網上資料有一下說法:

> 本地開發(fā),auth server與client都是localhost,造成JSESSIONID相互影響問題??梢酝ㄟ^配置client的context-path或者session名稱來解決

?? 根據這個描述,我嘗試通過修改 session名稱來解決:

server:
  servlet:
    session:
      cookie:
        name: OAUTH2CLIENTSESSION  # 解決  Possible CSRF detected - state parameter was required but no state could be found  問題

?? 重啟項目,測試SSO,完美解決?。?!

到此,關于“Spring Boot 從1.x升級到 2.x 后 單點登陸SSO問題的解決方法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注創(chuàng)新互聯(lián)網站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

新聞標題:SpringBoot從1.x升級到2.x后單點登陸SSO問題的解決方法
本文URL:http://muchs.cn/article40/jcjiho.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供網站建設、品牌網站設計網站排名、網站設計面包屑導航、網頁設計公司

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網站網頁設計