Spring Authorization Server 替换 Shiro 指引
背景
- Spring 团队正式宣布Spring Security OAuth 停止维护,该项目将不会再进行任何的迭代
![](http://dingyue.ws.126.net/2024/0306/fafd1e20j00s9x6xa008dd000u000c3m.jpg)
- 目前 Spring 生态中的 OAuth2 授权服务器是Spring Authorization Server已经可以正式生产使用
- 作为 SpringBoot 3.0 的最新权限方案,JeecgBoot springboot3_sas分支,已经完成了采用Spring Authorization Server 替换 Shiro工作。
JeecgBoot SAS分支
- Date: 2024-01-17
- 技术栈: SpringBoot3+ Spring Authorization Server+jdk18
源码下载:
- 后端:https://github.com/jeecgboot/jeecg-boot/tree/springboot3_sas
- 前端:https://github.com/jeecgboot/jeecgboot-vue3/tree/springboot3_sas
登录对接
- jeecg 基于Spring Authorization Server扩展了四种登录实现,加上默认提供的四种,共计有8种登录方式,额外还有OpenID Connect模式。本文不讲解授权码模式、客户端模式、刷新码模式、设备码模式、OpenID Connect模式,只会讲解jeecg实际应用了的四种扩展模式,其它模式请查阅Spring Authorization Server官方原文。
- https://docs.spring.io/spring-authorization-server/reference/overview.html
- 注意:OpenID Connect应当仅为认证阶段使用,不可作为权限校验阶段使用。
密码模式和APP模式
- 密码模式在Oauth2.1协议中被放弃,Spring Authorization Server并没有对该模式提供实现,该实现是基于Spring Authorization Server提供的扩展入口实现的。
- 密码模式实现源码:package org.jeecg.config.security.password;
- APP模式实现源码:package org.jeecg.config.security.app;
- 密码模式与APP模式实现完全一致,不过防止额外需求偏差,所以进行了分开实现。
请求地址:{baseUrl} /oauth2/token
请求方法:POST
请求头:
![](http://dingyue.ws.126.net/2024/0306/b9b522adp00s9x6y9000bd000cx003cp.png)
请求参数:
![](http://dingyue.ws.126.net/2024/0306/0351e8fdj00s9x6z3000fd000df004gp.jpg)
响应内容:
![](http://dingyue.ws.126.net/2024/0306/b3c7b3b1j00s9x701000nd000hl005ap.jpg)
phone模式
- phone模式用于手机+验证码登录场景。
- phone模式实现源码:package org.jeecg.config.security.phone;
请求地址:{baseUrl} /oauth2/token
请求方法:POST
请求头:
![](http://dingyue.ws.126.net/2024/0306/f65ca8ebp00s9x70q000bd000df003hp.png)
请求参数:
![](http://dingyue.ws.126.net/2024/0306/2a780045j00s9x71b0009d0005m004ep.jpg)
响应内容:
![](http://dingyue.ws.126.net/2024/0306/ff1279fbj00s9x721000nd000hq005cp.jpg)
social模式
- 任何一个用户中心端(比如微信、微博、github、gitee)对外提供的对接方式都是授权码模式、OpenID Connect模式,最终获取到一段用户信息(比如用户名、头像地址、邮箱),但是其实并没有办法拿着这段信息在当前系统中访问受限资源,以前都是手搓token或者其它手段来得到受限访问的权限,这种方法不可靠也不安全,而且也不易维护。
- jeecg针对以上场景,基于Spring Authorization Server扩展了social模式,用于处理获取三方用户信息后,再获取当前系统的访问凭证。
- social模式实现源码:package org.jeecg.config.security.social;
- 提示:文档中只讲解social模式的应用,不讲解从三方登录到应用social模式的全流程,jeecg前后端均已实现,细节请查看源码。
请求地址:{baseUrl} /oauth2/token
请求方法:POST
请求头:
![](http://dingyue.ws.126.net/2024/0306/309d8154p00s9x72r000bd000de003kp.png)
请求参数:
![](http://dingyue.ws.126.net/2024/0306/26f8480bj00s9x73j000ad000730046p.jpg)
响应内容:
![](http://dingyue.ws.126.net/2024/0306/7024e3fcj00s9x74d000nd000ho005ip.jpg)
权限校验
可用于方法或类上,将基于注解的权限code,针对性处理方法或当前类的所有接口进行权限拦截。
基于角色
//shiro用法
@RequiresRoles("admin")
//可替换为springauthorizationserver用法
@PreAuthorize("jps.requiresRoles('admin')")
基于权限
//shiro用法
@RequiresPermissions("sys:role")
//可替换为springauthorizationserver用法
@PreAuthorize("jps.requiresPermissions('sys:role')")
角色和权限组合使用
-@PreAuthorize("@jps.requiresPermissions('system:quartzJob:add')or@jps.requiresRoles('admin')")
免登录配置
jeecg:
shiro:
excludeUrls:/test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/jmreport/bigscreen2/**
#替换为
security:
oauth2:
client:
ignore-urls:
-/test/jeecgDemo/demo3
-/test/jeecgDemo/redisDemo/**
-/jmreport/bigscreen2/**
升级小技巧
![](http://dingyue.ws.126.net/2024/0306/0e1bee97j00s9x75l001bd000l40079p.jpg)
升级SQL
切换springboot3_sas分支的Spring Authorization Server,需要执行升级sql
CREATETABLE`oauth2_registered_client`(
`id`varchar(100)NOTNULL,
`client_id`varchar(100)NOTNULL,
`client_id_issued_at`timestampNOTNULLDEFAULTCURRENT_TIMESTAMP,
`client_secret`varchar(200)DEFAULTNULL,
`client_secret_expires_at`timestampNULLDEFAULTNULL,
`client_name`varchar(200)NOTNULL,
`client_authentication_methods`varchar(1000)NOTNULL,
`authorization_grant_types`varchar(1000)NOTNULL,
`redirect_uris`varchar(1000)DEFAULTNULL,
`post_logout_redirect_uris`varchar(1000)DEFAULTNULL,
`scopes`varchar(1000)NOTNULL,
`client_settings`varchar(2000)NOTNULL,
`token_settings`varchar(2000)NOTNULL,
PRIMARYKEY(`id`)
)ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COLLATE=utf8mb4_general_ci;
INSERTINTO`oauth2_registered_client`
(`id`,
`client_id`,
`client_id_issued_at`,
`client_secret`,
`client_secret_expires_at`,
`client_name`,
`client_authentication_methods`,
`authorization_grant_types`,
`redirect_uris`,
`post_logout_redirect_uris`,
`scopes`,
`client_settings`,
`token_settings`)
VALUES
('3eacac0e-0de9-4727-9a64-6bdd4be2ee1f',
'jeecg-client',
now(),
'secret',
null,
'3eacac0e-0de9-4727-9a64-6bdd4be2ee1f',
'client_secret_basic',
'refresh_token,authorization_code,password,app,phone,social',
'http://127.0.0.1:8080/jeecg-',
'http://127.0.0.1:8080/',
'*',
'{"@class":"java.util.Collections$UnmodifiableMap","settings.client.require-proof-key":false,"settings.client.require-authorization-consent":true}',
'{"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",300000.000000000],"settings.token.access-token-format":{"@class":"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat","value":"self-contained"},"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000],"settings.token.authorization-code-time-to-live":["java.time.Duration",300000.000000000],"settings.token.device-code-time-to-live":["java.time.Duration",300000.000000000]}');
常用API
1. 获取登录用户信息
LoginUser sysUser = SecureUtil.currentUser();
热门跟贴