/authorization-server

贵州民族大学授权服务器

Primary LanguageJavaMIT LicenseMIT

authorization-server

简述

很久以前就想让资源服务器、授权服务器、客户端完全分离的,年初的时候尝试过,但是由于那个时候能力有限,所以失败很多次,后来在考试系统项目初期,也再次尝试,可惜的是依旧失败,那时候真的很菜,不得已暂时将他们放在一个应用之中。最近由于毕业设计的需求的原因,再次需要将授权服务器分离,原本在 lesson-cloud 系统内的授权服务器,现在将它独立出来,作为一个单独的应用授权服务器进行使用。花了大概一天的时间完成整个移植过程,觉得自己进步了很多。

目前授权服务器内置我校的 6 张数据表,包括

  • sys_user 用户表

  • sys_role 角色表

  • sys_res 资源表

  • sys_user_role 用户角色关联表

  • sys_role_res 角色资源关联表

  • sys_data 数据表

  • client_details OAuth2 客户端信息

  • student 学生信息表

  • teacher 教师表

授权码模式示例

logout

任务

贵州民族大学授权服务器,专门用来为我校应用提供授权服务,使用 spring security oauth 进行完成,完成进度:

  • ✓ 密码模式、授权码模式

  • ✓ 手机验证码认证授权

  • ✓ 手机/邮箱验证码注册

  • ✓ 多应用认证授权服务器

  • ✓ jwt 信息非对称密钥加密

  • ✓ jwt 信息认证完整性填充

  • ✓ SSO 认证授权服务器

  • ✓ 微服务注册

  • ❏ 高并发处理

  • ❏ 集成测试完善

授权服务器

授权服务器的示例参见 resource-server 项目,他演示了一个简单的授权服务器的搭建。

技术选型

  • 构建工具: gradle 5

  • 授权协议: OAuth2

  • 核心框架: spring security oauth

  • 服务发现: spring cloud consul

  • 数据缓存: redis 5

  • 邮件模板: thymeleaf

  • 应用监控: actuator + druid

  • 单元测试: junit 5

  • 数据库: jpa + postgresql 8

基本认证授权

对于认证我们暂时提供三种认证方式,一种 密码认证手机验证码授权码模式 三种。提供以下端点:

  • /code/sms 获取手机验证码端点。

  • /oauth/sms 手机验证码认证端点。

  • /oauth/token 授权模式、密码认证 与 刷新令牌 端点。

  • /oauth/authorize 授权码模式授权端点。

  • /oauth/confirm_access 用户确认授权提交端点。

  • /oauth/error 授权服务错误信息端点。

  • /oauth/check_token 用于资源服务访问的令牌解析端点。

  • /oauth/token_key 提供公有密匙的端点,使用JWT令牌。

  • /.well-known/jwks.json JWK 令牌端点。

密码认证

使用 spring security oauth2 提供的默认密码登录即可,请求接口如下:

  • 请求路径:/oauth/token

  • 请求方法: POST

  • 请求头:

Table 1. 请求头
参数 描述

Authorization

Basic bGVzc29uLWNsb3VkOmxlc3Nvbi1jbG91ZC1zZWNyZXQ=

来自于 oauth client id 和 client secret base64 加密

  • 请求参数:

Table 2. 请求参数
参数 描述

grant_type

password

请求类型

scope

all

请求权限域

username

-

用户名

password

-

密码

  • 正确响应:

Table 3. 正确响应
属性 描述

access_token

jwt 加密后令牌

token_type

令牌类型,默认 bearer

refresh_token

用来刷新的令牌

expires_in

有效期

scope

请求域,默认 all

jti

JWT ID

  • 错误响应

Table 4. 错误响应
状态码 错误原因 错误(error) 错误信息(error_message)

401

请求头中不含有 Authorization 属性

unauthorized

Full authentication is required to access this resource

400

grant_type 参数错误

unsupported_grant_type

Unsupported grant type: …​

400

scope 参数错误

invalid_scope

Invalid scope:…​

400

用户名或密码错误

invalid_grant

用户名或密码错误

这里原理我就不介绍了,是由 spring security oauth2 实现的,有兴趣可以去看看源码。他的核心是 org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter 这个过滤器。

手机验证码认证

手机验证码认证分为两步,第一步为下发验证码,第二步为携带验证码和手机号请求认证。

获取验证码

由于目前没有真正的手机提供商,所以我不会真正的发短信,但是会默认短信验证码为 1234 并存储到 redis 之中。

  • 请求路径:/code/sms

  • 请求方式: GET

  • 请求头:

Table 5. 请求头
参数 描述

sms

-

手机号

  • 请求参数: 无

  • 正确响应:

Table 6. 正确响应
状态码 响应体

200

  • 错误响应:

Table 7. 错误响应
状态码 错误原因 错误(error) 错误信息(error_message)

401

请求头中不含有 sms 属性

unauthorized

请求中不存在设备号

手机认证

  • 请求路径:/oauth/sms

  • 请求方式: POST

  • 请求头:

Table 8. 请求头
参数 描述

Authorization

Basic bGVzc29uLWNsb3VkOmxlc3Nvbi1jbG91ZC1zZWNyZXQ=

来自于 oauth client id 和 client secret base64 加密

sms

-

手机号

code

-

验证码

  • 正确响应:

Table 9. 正确响应
属性 描述

access_token

jwt 加密后令牌

token_type

令牌类型,默认 bearer

refresh_token

用来刷新的令牌

expires_in

有效期

scope

请求域,默认 all

jti

JWT ID

  • 错误响应: 待封装

Table 10. 错误响应
状态码 错误原因 错误(error) 错误信息(error_message)

400

请求体中不含有 sms 属性或者验证码验证失败

获取验证码失败,请重新发送

获取验证码失败,请重新发送

400

请求头中不含有 sms 属性

请求中不存在设备号

请求中不存在设备号

原理

获取手机验证码主要在 cn.edu.gzmu.authserver.validate.sms 下,具体请参见 cn/edu/gzmu/authserver/validate/package-info.java

手机验证主要在 cn.edu.gzmu.authserver.auth.sms,具体请参见 cn/edu/gzmu/authserver/auth/sms/package-info.java

刷新令牌

  • 请求路径:/oauth/token

  • 请求方式: POST

  • 请求头:

Table 11. 请求头
参数 描述

Authorization

Basic bGVzc29uLWNsb3VkOmxlc3Nvbi1jbG91ZC1zZWNyZXQ=

来自于 oauth client id 和 client secret base64 加密

  • 请求体:

Table 12. 请求头
参数 描述

grant_type

refresh_token

刷新验证码

refresh_token

-

获取 token 时候得到的 refresh_token

  • 正确响应:

Table 13. 正确响应
属性 描述

access_token

jwt 加密后令牌

token_type

令牌类型,默认 bearer

refresh_token

用来刷新的令牌

expires_in

有效期

scope

请求域,默认 all

jti

JWT ID

  • 错误响应:

Table 14. 错误响应
状态码 错误原因 错误(error) 错误信息(error_message)

401

请求头中不含有 Authorization 属性

unauthorized

Full authentication is required to access this resource

400

grant_type 参数错误

unsupported_grant_type

Unsupported grant type: …​

400

refresh_token 不合法

invalid_grant

Invalid refresh token:…​

检查 token 信息

  • 请求路径:/oauth/check_token

  • 请求方式: POST

  • 请求头:

Table 15. 请求头
参数 描述

Authorization

Basic bGVzc29uLWNsb3VkOmxlc3Nvbi1jbG91ZC1zZWNyZXQ=

来自于 oauth client id 和 client secret base64 加密

  • 请求体:

Table 16. 请求头
参数 描述

token

-

有效的 token

  • 正确响应:

Table 17. 正确响应
属性 描述

aud

授权的资源服务器名称

user_name

用户名

scope

有效的域

active

是否存活

exp

有效期

authorities

授权角色

jti

jwt id

client_id

客户端 id