代码位置:
https://github.com/andyzhaozhao/spring-security-oauth2-sample
我们前面使用Spring Social实现过社交账号登录的功能,这在Spring Security 4.x的版本中是较为普遍的做法,Spring Boot 1.x也为Spring Social提供过简单的自动配置, 但这些在Spring Boot 2.x和Spring Security 5.x的技术栈中就被移除了,因为从Spring Security 5.0版本开始,官方逐渐把原独立项目Spring Security OAuth的功能集成了进来,Spring Social自然也就变得多余了。
Spring Security OAuth是一个专注于OAuth认证的框架,它完整覆盖了客户端、资源服务、认证服务三大模块,并分别在Spring Security 5.0、5.1和5.3三个版本中被集成,原有的独立项目则进入了维护状态。从趋势上来说,Spring Security集成的OAuth将是一个比Spring Social更好的选择。
在Spring Security 5.0的版本中,由于只集成了OAuth的客户端功能,所以也只有三个子模块:
- spring-security-oauth2-core OAuth2授权框架和OIDC的核心数据结构和接口,被Client、Resource Server和Authorization Server依赖
spring-security-oauth2-jose 对JOSE协议组的支持,具体包括:
- JSON Web Token (JWT)
- JSON Web Signature (JWS)
- JSON Web Encryption (JWE)
- JSON Web Key (JWK)
- spring-security-oauth2-client 是Spring Security支持OAuth2和OIDC的Client功能实现包。
接下来我们将快速体验一下Spring Security的OAuth功能。考虑到接入成本等问题,推荐使用Github作为OAuth2服务提供商,因为Github在国内可以正常访问,其提供的认证服务也符合标准的OAuth2协议,并且Github账号申请较为方便,这些因素都有利于我们聚焦Spring Security的OAuth2客户端接入流程。
编码实现
1. 新建工程
首先,新建Spring Boot 2.0工程,pom包依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2. 在Github官网注册OAuth2应用
首先需要在Github官网注册一个新的OAuth2应用,地址是:https://github.com/settings/applications/new ,打开如图1所示:
- Application Name,必填,可以随意起一个应用名称。
- Homepage URL,必填,本地开发环节,设置为http://localhost:8080即可。
- Application description,选填,应用的说明,置空即可。
- Authorization callback URL,必填,OAuth认证的重定向地址,本地开发环节可设置为http://localhost:8080/login/oauth2/code/github。
确认完成,点击Register appcation按钮即可注册得到clientId和clientSecret。
当用户通过用户代理(浏览器)成功登录Github,并且用户在批准页(Approva Page)授权允许注册的客户端应用访问自己的用户数据后,Github会将授权码(code)通过重定向方式传递给客户端应用。Spring Security OAuth默认的重定向模版是{baseUrl}/login/oauth2/code/{registrationId},registrationId表示的是ClientRegistration的唯一ID,我们通常会以接入的OAuth服务商的简称来命名,所以此处设置为github。
3. 配置application.yml
前面我们已经在工程的pom文件中引入了相关依赖包,并且在GitHub上也成功注册了一个OAuth2客户端应用,接下来还需要在配置文件application.yml中增加相应配置:
spring:
security:
oauth2:
client:
registration: (1)
github: (2)
client-id: github-client-id
client-secret: github-client-secret
说明:
- spring.security.oauth2.client.registration是OAuth2客户端所有属性的基础前缀。
- registration下面的github表示的是ClientRegistration的唯一ID。
另外,client-id和client-secret需要替换为我们前面在Github上注册得到的clientId和clientSecret。
4. 新建Controller
@RestController
public class SimpleController {
@GetMapping("/hello")
public String hello(Principal principal) {
return "hello," + principal.getName();
}
}
参数中的Principal对象由Spring框架自动注入,表示当前登录的用户。
5. 效果演示
- 启动我们新建的OAuth2工程。
- 浏览器访问 http://localhost:8080/hello 时将首先重定向到默认生成的登录页,点击GitHub按钮则跳转到Github登录页,如图2:
当认证成功时将会跳转到确认授权页面,如图3:
点击确定按钮,以授权允许OAuth2客户端应用访问Github的用户数据,此时OAuth2客户端应用会调用用户数据接口(the UserInfo Endpoint)创建认证对象,如果一切顺利,浏览器最终将自动重定向到原访问地址:http://localhost:8080/hello ,并打印字符串“hello,xxx”。