最近一段时间,你们在用 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 教程,欢迎你们关注~