最近一段時間,你們在用 Spring Security OAuth2 時可能發現有不少類過時了。java
你們在選擇 OAuth2 依賴的時候,可能也會困惑,有好幾個地方均可以選:git
那麼到底選擇哪個依賴合適呢?這不一樣的依賴又有什麼區別?今天鬆哥就來和你們聊一聊 Spring Security 中關於 OAuth2 的恩怨。github
先來大體介紹一下 OAuth2 在 Spring 框架中的發展歷程。spring
大約十年前,Spring 引入了一個社區驅動的開源項目 Spring Security OAuth,並將其歸入 Spring 項目組合中。到今天,它已經發展成爲一個成熟的項目,能夠支持大部分 OAuth 規範,包括資源服務器
、客戶端
和受權服務器
等。安全
如今它已成爲 UAA(User Account and Authentication Server) 的基礎。Spring Security OAuth 項目已成爲一個樣板項目,它證實了 Spring 社區能夠出色的完成工做。服務器
然而早期的項目存在這樣一些問題:框架
基於以上這些緣由,官方決定在社區成功的基礎上,重寫 Spring Security OAuth,以更好地協調 Spring 和 OAuth,並簡化代碼庫,以使 Spring 的 OAuth 支持更加靈活。ide
然而,在重寫的過程當中,發生了很多波折。學習
事情得從 2018 年 1 月 30 號講起。spa
那天 Spring 官方發了一個通知,說是要逐漸中止現有的 OAuth2 支持,而在 Spring Security5 中構建下一代 OAuth2.0 支持。
爲何要這樣呢?
你們知道,OAuth2 只是一種協議,Spring 框架經過代碼對這種協議進行落地。
當時 OAuth2 的落地方案比較混亂(這種混亂到今天依然存在),在 Spring Security OAuth、Spring Cloud Security、Spring Boot 1.5.x 以及當時最新的 Spring Security5.x 中都提供了對 OAuth2 的實現。
以致於當開發者須要使用 OAuth2 時,不得不問,到底選哪個依賴合適呢?已經有三個地方提供了 OAuth2 的支持,已經夠混亂了,爲何還要在最新的 Spring Security5.x 中繼續提供實現呢?
太亂了!
因此 Spring 官方決定有必要將 OAuth2.0 的支持統一到一個項目中,以便爲用戶提供明確的選擇並避免任何潛在的混亂,同時 OAuth2 的開發文檔也要從新編寫,以方便開發人員學習。全部的決定將在 Spring Security5 中開始,構建下一代 OAuth2.0 的支持。
從那個時候起,Spring Security OAuth 項目就正式處於維護模式。官方將提供至少 1 年的錯誤/安全修復程序,而且會考慮添加次要功能,但不會添加主要功能。同時將 Spring Security OAuth 中的全部功能重構到 Spring Security5.x 中。
老實說,這是一個英明的決定,當時並無引發太多的反響。可是接下來的事情就不是那麼順利了。
時間到了 2019.11.14。
這天,官方又發了個通知。
先說了 Spring Security OAuth 在遷往 Spring Security5.x 的過程很是順利,大部分遷移工做已經完成了,剩下的將在 5.3 版本中完成遷移,在遷移的過程當中還添加了許多新功能,包括對 OpenID Connect1.0 的支持
接下來話鋒一轉,說了一件不少人難以接受的事情,那就是將再也不提供對受權服務器的支持(要是小夥伴們不懂什麼是受權服務器,能夠在公衆號江南一點雨後臺回覆 OAuth2
,有鬆哥寫的 OAuth2 教程)。
不提供的緣由,官方給了兩個:
一石激起千層浪,許多開發者表示對此難以接受。這件事也在 Spring 社區引起了激烈的討論,好在 Spring 官方願意傾聽來自社區的聲音。
這天,官方又發了個通知。
此次宣佈了 Spring Authorization Server 項目。這是一個由 Spring Security 團隊領導的社區驅動的項目,致力於向 Spring 社區提供 Authorization Server 支持。
官方傾聽了來自社區的聲音,決定繼續提供受權服務器。
此次只是宣佈了一下,算是安撫了一下社區的情緒,可是項目還沒開發出來。
Spring Authorization Server 0.0.1 正式發佈!
同時公佈了項目源碼地址:https://github.com/spring-pro...
在這個版本中,主要提供了以下功能:
其餘功能還在緊鑼密鼓的開發中。
這就是 OAuth2 最近幾年的變動之路。
回到最開始的問題。
類過時了怎麼辦?
類過時是由於舊的寫法已經不被支持,鬆哥舉個簡單例子,之前咱們定義資源服務器是這樣的:
@Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Bean RemoteTokenServices tokenServices() { RemoteTokenServices services = new RemoteTokenServices(); services.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token"); services.setClientId("javaboy"); services.setClientSecret("123"); return services; } @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.resourceId("res1").tokenServices(tokenServices()); } @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("admin") .anyRequest().authenticated(); } }
如今遷移到 Spring Security5.x 中以後,咱們是這樣定義的:
@Configuration public class MyResourceServer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and() .oauth2ResourceServer() .opaqueToken() .introspectionUri("http://localhost:8080/oauth/check_token") .introspectionClientCredentials("javaboy", "123"); } }
這兩段代碼做用是同樣的。後面的是目前最新寫法,不存在過時的問題。
選哪一個依賴
如今你們已經知道爲何會存在多種不一樣的依賴,Spring Cloud Security OAuth2 中使用舊的寫法並不會提示過時,可是它同時也支持新的寫法,建議小夥伴們用新的寫法,反正早晚都要改過來。
鬆哥在四月份的時候出了一個 OAuth2 的教程,當時就是基於 Spring Cloud Security OAuth2 來作的,用了舊的寫法,可是沒有提示過時的問題,感興趣的小夥伴能夠看看(公衆號後臺回覆 OAuth2),不管新舊,只要會其中一個,另一個上手就很容易了。
固然,後面我也會結合最新的 Spring Security5.x 來更新一套 OAuth2 教程,歡迎你們關注~