Sa-Token OAuth2.0 实现
Sa-Token 提供了一套完整的 OAuth2.0 实现方案,支持多种授权模式(如授权码模式、密码模式、客户端模式等)。本文将详细介绍如何搭建 OAuth2-Server,并解析各授权模式的核心逻辑与使用方法。
OAuth2-Server 搭建
Sa-Token 的 OAuth2.0 实现提供了一套完整的 OAuth2-Server 搭建方案,支持多种授权模式(如授权码模式、密码模式、客户端模式等)。以下将详细介绍如何搭建一个 OAuth2-Server,并配置其核心功能。
1. 初始化 OAuth2-Server 配置
首先,需要在项目中初始化 SaOAuth2ServerConfig 配置类,设置 OAuth2-Server 的基本参数。以下是一个典型的配置示例:
@Configuration
public class SaOAuth2ServerConfig {
@Bean
public SaOAuth2ServerConfig getSaOAuth2ServerConfig() {
SaOAuth2ServerConfig config = new SaOAuth2ServerConfig();
// 启用授权码模式
config.setEnableAuthorizationCode(true);
// 设置令牌有效期(单位:秒)
config.setAccessTokenTimeout(7200); // 2小时
config.setRefreshTokenTimeout(2592000); // 30天
// 添加客户端配置
SaClientModel client = new SaClientModel()
.setClientId("client1")
.setClientSecret("123456")
.setContractScopes(Arrays.asList("userinfo", "email"))
.setAllowRedirectUris(Arrays.asList("http://localhost:8080/callback"));
config.addClient(client);
return config;
}
}
2. 配置 OAuth2-Server 处理器
Sa-Token 提供了 SaOAuth2ServerProcessor 类,用于处理 OAuth2.0 的核心逻辑(如授权、令牌颁发等)。以下是一个简单的控制器示例:
@RestController
@RequestMapping("/oauth2")
public class SaOAuth2ServerController {
@GetMapping("/authorize")
public Object authorize(@RequestParam String response_type, @RequestParam String client_id,
@RequestParam String redirect_uri, @RequestParam(required = false) String scope) {
return SaOAuth2ServerProcessor.instance.authorize();
}
@PostMapping("/token")
public Object token(@RequestParam String grant_type, @RequestParam(required = false) String code,
@RequestParam(required = false) String refresh_token) {
return SaOAuth2ServerProcessor.instance.token();
}
}
3. 支持的授权模式
Sa-Token 的 OAuth2-Server 支持以下授权模式:
| 授权模式 | 描述 |
|---|---|
| 授权码模式 | 适用于 Web 应用,通过授权码交换令牌。 |
| 密码模式 | 适用于信任的客户端,直接通过用户名和密码获取令牌。 |
| 客户端模式 | 适用于无用户参与的客户端,直接通过客户端凭证获取令牌。 |
| 刷新令牌模式 | 通过刷新令牌获取新的访问令牌。 |
4. 数据库存储配置
OAuth2-Server 需要存储令牌、授权码等数据。Sa-Token 提供了 SaOAuth2Dao 接口,支持自定义存储实现。以下是一个基于 Redis 的存储配置示例:
@Configuration
public class SaOAuth2DaoConfig {
@Bean
public SaOAuth2Dao getSaOAuth2Dao() {
return new SaOAuth2Dao() {
@Override
public void saveCode(CodeModel code) {
// 存储授权码逻辑
}
@Override
public CodeModel getCode(String code) {
// 获取授权码逻辑
return null;
}
};
}
}
5. 流程图:OAuth2-Server 授权流程
以下是一个典型的授权码模式流程图:
sequenceDiagram
participant Client
participant Server
participant User
Client->>Server: 发起授权请求
Server->>User: 显示授权页面
User->>Server: 确认授权
Server->>Client: 返回授权码
Client->>Server: 使用授权码请求令牌
Server->>Client: 返回访问令牌和刷新令牌
6. 总结
通过以上步骤,可以快速搭建一个功能完善的 OAuth2-Server。Sa-Token 提供了灵活的配置选项和强大的扩展能力,能够满足各种场景的需求。在实际开发中,可以根据业务需求进一步定制化配置和存储逻辑。
授权码模式
授权码模式(Authorization Code Grant)是OAuth2.0中最常用的授权模式之一,适用于需要用户授权的场景。Sa-Token的OAuth2.0模块提供了完整的授权码模式实现,支持标准的OAuth2.0流程,包括授权码的生成、验证以及令牌的发放。
授权码模式流程
授权码模式的流程可以分为以下几个步骤:
- 用户授权请求:客户端将用户重定向到授权服务器,请求授权。
- 用户授权:用户在授权服务器上登录并授权。
- 授权码发放:授权服务器生成授权码并返回给客户端。
- 令牌请求:客户端使用授权码向授权服务器请求令牌。
- 令牌发放:授权服务器验证授权码后发放访问令牌和刷新令牌。
以下是一个典型的授权码模式流程图:
sequenceDiagram
participant Client as 客户端
participant User as 用户
participant AuthServer as 授权服务器
User->>Client: 访问客户端
Client->>AuthServer: 重定向到授权页面
User->>AuthServer: 登录并授权
AuthServer->>Client: 返回授权码
Client->>AuthServer: 使用授权码请求令牌
AuthServer->>Client: 返回访问令牌和刷新令牌
核心类与功能
Sa-Token的授权码模式实现依赖于以下几个核心类:
AuthorizationCodeGrantTypeHandler:处理授权码模式的令牌请求逻辑。SaOAuth2ServerConfig:配置授权码模式的启用状态及相关参数。SaOAuth2Template:提供授权码验证和令牌生成的模板方法。CodeModel:封装授权码的数据模型。
1. AuthorizationCodeGrantTypeHandler
AuthorizationCodeGrantTypeHandler是授权码模式的核心处理器,负责验证授权码并生成访问令牌。以下是其关键方法:
@Override
public AccessTokenModel getAccessToken(SaRequest req, String clientId, List<String> scopes) {
// 验证授权码并生成令牌
String code = req.getParam(Param.code);
String redirectUri = req.getParam(Param.redirect_uri);
CodeModel cm = SaOAuth2Manager.getTemplate().checkGainTokenParam(code, clientId, null, redirectUri);
return SaOAuth2Manager.getDataGenerate().generateAccessToken(code);
}
2. SaOAuth2ServerConfig
SaOAuth2ServerConfig用于配置授权码模式的启用状态及相关参数。以下是关键配置项:
public class SaOAuth2ServerConfig {
// 是否启用授权码模式
private Boolean enableAuthorizationCode = true;
// 授权码超时时间(毫秒)
private long codeTimeout = 300000; // 5分钟
}
3. SaOAuth2Template
SaOAuth2Template提供了授权码验证的模板方法,确保授权码的有效性:
public CodeModel checkGainTokenParam(String code, String clientId, String clientSecret, String redirectUri) {
CodeModel cm = getCode(code);
SaOAuth2AuthorizationCodeException.throwBy(cm == null, "无效 code: " + code, code, SaOAuth2ErrorCode.CODE_30110);
return cm;
}
4. CodeModel
CodeModel封装了授权码的数据模型,包含以下字段:
public class CodeModel {
private String code; // 授权码
private String clientId; // 客户端ID
private Object loginId; // 用户ID
private String redirectUri; // 重定向URI
private List<String> scopes; // 授权范围
}
示例代码
以下是一个完整的授权码模式示例:
- 客户端发起授权请求:
String authUrl = "http://auth-server/oauth2/authorize?response_type=code&client_id=client1&redirect_uri=http://client/callback";
response.sendRedirect(authUrl);
- 授权服务器生成授权码:
CodeModel cm = new CodeModel()
.setCode(UUID.randomUUID().toString())
.setClientId("client1")
.setLoginId("user1")
.setRedirectUri("http://client/callback");
SaOAuth2Manager.getDao().saveCode(cm);
- 客户端使用授权码请求令牌:
String tokenUrl = "http://auth-server/oauth2/token?grant_type=authorization_code&code=xxx&redirect_uri=http://client/callback";
AccessTokenModel token = SaOAuth2Manager.getTemplate().token(tokenUrl);
总结
授权码模式是OAuth2.0中最安全的授权方式之一,适用于需要用户交互的场景。Sa-Token通过AuthorizationCodeGrantTypeHandler、SaOAuth2ServerConfig等核心类提供了完整的实现,开发者可以轻松集成到自己的项目中。
Sa-Token OAuth2.0 实现:密码模式详解
OAuth2.0 的密码模式(Password Grant Type)是一种直接通过用户名和密码获取访问令牌的方式,适用于高度信任的场景。Sa-Token 提供了完整的密码模式实现,本文将深入解析其核心逻辑、使用方法和注意事项。
密码模式的核心逻辑
密码模式的流程如下:
- 客户端请求:客户端将用户名和密码直接发送到授权服务器。
- 服务器验证:授权服务器验证用户名和密码的有效性。
- 令牌发放:验证通过后,服务器返回访问令牌(Access Token)和可选的刷新令牌(Refresh Token)。
以下是 Sa-Token 中密码模式的核心代码实现:
public class PasswordGrantTypeHandler implements SaOAuth2GrantTypeHandlerInterface {
@Override
public String getHandlerGrantType() {
return GrantType.password;
}
@Override
public AccessTokenModel getAccessToken(SaRequest req, String clientId, List<String> scopes) {
String username = req.getParamNotNull(SaOAuth2Consts.Param.username);
String password = req.getParamNotNull(SaOAuth2Consts.Param.password);
PasswordAuthResult passwordAuthResult = loginByUsernamePassword(username, password);
Object loginId = passwordAuthResult.getLoginId();
RequestAuthModel ra = new RequestAuthModel(clientId, scopes, loginId);
return SaOAuth2Manager.getDataGenerate().generateAccessToken(ra, true, atm -> atm.grantType = GrantType.password);
}
public PasswordAuthResult loginByUsernamePassword(String username, String password) {
System.err.println("警告信息:当前 password 认证模式,使用默认实现 (SaOAuth2Strategy.instance.doLoginHandle),仅供开发测试");
return SaOAuth2Strategy.instance.doLoginHandle.apply(username, password);
}
}
使用方法
1. 启用密码模式
在 Sa-Token 的 OAuth2.0 配置中,需显式启用密码模式:
SaOAuth2ServerConfig config = new SaOAuth2ServerConfig();
config.setEnablePassword(true);
2. 自定义登录逻辑
默认的 loginByUsernamePassword 方法仅用于测试,实际项目中需重写此方法以实现自定义的用户名密码验证逻辑:
public class CustomPasswordGrantTypeHandler extends PasswordGrantTypeHandler {
@Override
public PasswordAuthResult loginByUsernamePassword(String username, String password) {
if ("sa".equals(username) && "123456".equals(password)) {
return new PasswordAuthResult().setLoginId("10001");
}
throw new SaOAuth2Exception("用户名或密码错误");
}
}
3. 注册自定义处理器
将自定义处理器注册到 Sa-Token 的策略中:
SaOAuth2Strategy.instance.registerGrantTypeHandler(new CustomPasswordGrantTypeHandler());
注意事项
- 安全性:密码模式直接将用户凭证暴露给客户端,仅适用于高度信任的场景(如第一方应用)。
- 令牌有效期:建议设置较短的访问令牌有效期,并通过刷新令牌续期。
- 日志记录:记录所有密码模式的请求,便于审计和异常排查。
示例流程图
sequenceDiagram
participant Client
participant Server
Client->>Server: POST /token (grant_type=password&username=sa&password=123456)
Server->>Server: 验证用户名和密码
alt 验证成功
Server-->>Client: 返回 Access Token 和 Refresh Token
else 验证失败
Server-->>Client: 返回错误信息
end
通过以上内容,您可以快速掌握 Sa-Token 中密码模式的实现与使用方法。
客户端凭证模式
OAuth2.0 的客户端凭证模式(Client Credentials Grant)是一种适用于机器对机器(M2M)通信的授权模式。它允许客户端直接使用自己的凭证(Client ID 和 Client Secret)获取访问令牌,而无需用户参与。这种模式适用于后台服务之间的通信,例如微服务之间的调用。
核心流程
客户端凭证模式的流程如下:
sequenceDiagram
participant Client as 客户端
participant AuthServer as 授权服务器
Client->>AuthServer: 1. 请求令牌 (Client ID + Client Secret + grant_type=client_credentials)
AuthServer-->>Client: 2. 返回访问令牌 (Access Token)
- 客户端请求令牌:客户端向授权服务器发送请求,携带
client_id、client_secret和grant_type=client_credentials。 - 授权服务器验证:授权服务器验证客户端的凭证,并生成访问令牌。
- 返回令牌:授权服务器将访问令牌返回给客户端。
代码实现
在 Sa-Token 中,客户端凭证模式的实现主要涉及以下几个核心类:
GrantType:定义了client_credentials作为授权类型。SaOAuth2ServerProcessor:处理客户端凭证模式的令牌请求。SaClientModel:存储客户端的配置信息,包括允许的授权类型。
示例代码
以下是一个客户端凭证模式的请求示例:
// 客户端请求令牌
String tokenUrl = "http://auth-server.com/oauth2/token";
Map<String, String> params = new HashMap<>();
params.put("client_id", "your_client_id");
params.put("client_secret", "your_client_secret");
params.put("grant_type", "client_credentials");
// 发送请求
String response = HttpUtil.post(tokenUrl, params);
System.out.println("Access Token: " + response);
服务端配置
在 Sa-Token 中,可以通过 SaOAuth2ServerConfig 配置是否启用客户端凭证模式:
@Configuration
public class SaOAuth2Config {
@Bean
public SaOAuth2ServerConfig saOAuth2ServerConfig() {
return new SaOAuth2ServerConfig()
.setEnableClientCredentials(true) // 启用客户端凭证模式
.addClient(new SaClientModel()
.setClientId("your_client_id")
.setClientSecret("your_client_secret")
.addAllowGrantTypes("client_credentials")); // 允许客户端凭证模式
}
}
适用场景
客户端凭证模式适用于以下场景:
- 后台服务调用:微服务之间的 API 调用。
- 自动化任务:定时任务或批处理作业。
- 无用户交互:不需要用户参与的机器对机器通信。
注意事项
- 安全性:客户端凭证模式依赖于
client_secret,必须确保其安全性,避免泄露。 - 权限控制:客户端获取的访问令牌通常具有较高的权限,需严格控制其访问范围。
- 刷新令牌:客户端凭证模式不支持刷新令牌,访问令牌过期后需重新获取。
通过 Sa-Token 的 OAuth2.0 实现,可以轻松集成客户端凭证模式,满足后台服务的安全通信需求。
Sa-Token 的 OAuth2.0 实现提供了灵活且安全的授权方案,适用于各种场景。通过本文的介绍,您可以快速掌握如何搭建 OAuth2-Server 并集成不同的授权模式。无论是 Web 应用、微服务还是自动化任务,Sa-Token 都能满足您的需求。
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00- QQwen3-Coder-Next2026年2月4日,正式发布的Qwen3-Coder-Next,一款专为编码智能体和本地开发场景设计的开源语言模型。Python00
xw-cli实现国产算力大模型零门槛部署,一键跑通 Qwen、GLM-4.7、Minimax-2.1、DeepSeek-OCR 等模型Go06
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin08
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00