在https://blog.csdn.net/icarusliu/article/details/87911093一文中,介绍了OAuth的一些背景知识;本文将编写一个简单的示例,演示授权模式中的密码模式及客户端模式如何实现。
本示例中涉及到的几个对象其关系如下图所示:
密码模式一般用于用户对客户端信任度最高的情况下,因为客户端需要保存用户在授权服务器中的用户名及密码信息,客户端可以访问所有用户资源,因此一般在公司内部应用之间使用的较多。比如一个公司前端一般有安卓应用、苹果应用、Web端等,这个时候用户通过客户端使用用户名与密码登录的时候,这些信息实际上是告诉了客户端了,客户端可以拿这些信息来做任何用户权限内的事情。
在密码模式中,其处理流程如下:
- 客户端在授权服务器端的注册;
- 用户登录客户端,输入用户名及密码(或以某种其它方式保存用户在授权服务器中的用户名与密码);
- 客户端访问授权服务器验证授权,并获取访问Token;
- 客户端在后续的每次访问中都带上Token进行访问。
- 资源服务器接收到请求后,调用授权服务器相关接口校验Token有效性;
- Token有效时,进行实际的业务逻辑处理;
- Token有效时,返回相应错误信息给客户端;
另外,资源服务器与授权服务器可以在一个应用中,也可以分开。本文主要讲述分开处理时的实现,关于集中式实现请参考Spring Security OAuth的官方示例。
1. 授权服务器
授权服务器需要完成以下事情:
- 管理客户端及其授权信息;
- 管理用户及其授权信息;
- 管理Token的生成及其存储;
- 管理Token的校验及校验Key;
通过定义继承自AuthorizationServerConfigurerAdapter的一个配置类,以及Spring Security的配置,可以完成以上处理。
先来看授权服务器的最终配置:
1.1 MVN
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
1.2 Spring Security配置
通过Spring Security来完成用户及密码加解密等配置。
@Configuration
@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder