mirror of
https://gitee.com/dromara/sa-token.git
synced 2024-12-03 04:17:37 +08:00
commit
eb1ec5676c
@ -18,7 +18,7 @@ import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* Sa-Token-OAuth2 请求处理类封装
|
||||
* Sa-Token-OAuth2 请求处理类封装
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@ -26,195 +26,195 @@ public class SaOAuth2Handle {
|
||||
|
||||
/**
|
||||
* 处理Server端请求, 路由分发
|
||||
* @return 处理结果
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object serverRequest() {
|
||||
|
||||
// 获取变量
|
||||
|
||||
// 获取变量
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||
|
||||
// ------------------ 路由分发 ------------------
|
||||
|
||||
|
||||
// ------------------ 路由分发 ------------------
|
||||
|
||||
// 模式一:Code授权码
|
||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.code) && cfg.isCode) {
|
||||
return authorize(req, res, cfg);
|
||||
}
|
||||
|
||||
// Code授权码 获取 Access-Token
|
||||
// Code授权码 获取 Access-Token
|
||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.authorization_code)) {
|
||||
return token(req, res, cfg);
|
||||
}
|
||||
|
||||
// Refresh-Token 刷新 Access-Token
|
||||
|
||||
// Refresh-Token 刷新 Access-Token
|
||||
if(req.isPath(Api.refresh) && req.isParam(Param.grant_type, GrantType.refresh_token)) {
|
||||
return refreshToken(req);
|
||||
}
|
||||
|
||||
// 回收 Access-Token
|
||||
// 回收 Access-Token
|
||||
if(req.isPath(Api.revoke)) {
|
||||
return revokeToken(req);
|
||||
}
|
||||
|
||||
// doLogin 登录接口
|
||||
|
||||
// doLogin 登录接口
|
||||
if(req.isPath(Api.doLogin)) {
|
||||
return doLogin(req, res, cfg);
|
||||
}
|
||||
|
||||
// doConfirm 确认授权接口
|
||||
|
||||
// doConfirm 确认授权接口
|
||||
if(req.isPath(Api.doConfirm)) {
|
||||
return doConfirm(req);
|
||||
}
|
||||
|
||||
// 模式二:隐藏式
|
||||
|
||||
// 模式二:隐藏式
|
||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.token) && cfg.isImplicit) {
|
||||
return authorize(req, res, cfg);
|
||||
}
|
||||
|
||||
// 模式三:密码式
|
||||
|
||||
// 模式三:密码式
|
||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.password) && cfg.isPassword) {
|
||||
return password(req, res, cfg);
|
||||
}
|
||||
|
||||
// 模式四:凭证式
|
||||
// 模式四:凭证式
|
||||
if(req.isPath(Api.client_token) && req.isParam(Param.grant_type, GrantType.client_credentials) && cfg.isClient) {
|
||||
return clientToken(req, res, cfg);
|
||||
}
|
||||
|
||||
// 默认返回
|
||||
|
||||
// 默认返回
|
||||
return SaOAuth2Consts.NOT_HANDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 模式一:Code授权码 / 模式二:隐藏式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object authorize(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 1、如果尚未登录, 则先去登录
|
||||
/**
|
||||
* 模式一:Code授权码 / 模式二:隐藏式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object authorize(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 1、如果尚未登录, 则先去登录
|
||||
if(StpUtil.isLogin() == false) {
|
||||
return cfg.notLoginView.get();
|
||||
}
|
||||
|
||||
// 2、构建请求Model
|
||||
// 2、构建请求Model
|
||||
RequestAuthModel ra = SaOAuth2Util.generateRequestAuth(req, StpUtil.getLoginId());
|
||||
|
||||
// 3、校验:重定向域名是否合法
|
||||
// 3、校验:重定向域名是否合法
|
||||
SaOAuth2Util.checkRightUrl(ra.clientId, ra.redirectUri);
|
||||
|
||||
// 4、校验:此次申请的Scope,该Client是否已经签约
|
||||
// 4、校验:此次申请的Scope,该Client是否已经签约
|
||||
SaOAuth2Util.checkContract(ra.clientId, ra.scope);
|
||||
|
||||
// 5、判断:如果此次申请的Scope,该用户尚未授权,则转到授权页面
|
||||
// 5、判断:如果此次申请的Scope,该用户尚未授权,则转到授权页面
|
||||
boolean isGrant = SaOAuth2Util.isGrant(ra.loginId, ra.clientId, ra.scope);
|
||||
if(isGrant == false) {
|
||||
return cfg.confirmView.apply(ra.clientId, ra.scope);
|
||||
}
|
||||
|
||||
// 6、判断授权类型
|
||||
// 如果是 授权码式,则:开始重定向授权,下放code
|
||||
|
||||
// 6、判断授权类型
|
||||
// 如果是 授权码式,则:开始重定向授权,下放code
|
||||
if(ResponseType.code.equals(ra.responseType)) {
|
||||
CodeModel codeModel = SaOAuth2Util.generateCode(ra);
|
||||
CodeModel codeModel = SaOAuth2Util.generateCode(ra);
|
||||
String redirectUri = SaOAuth2Util.buildRedirectUri(ra.redirectUri, codeModel.code, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
// 如果是 隐藏式,则:开始重定向授权,下放 token
|
||||
// 如果是 隐藏式,则:开始重定向授权,下放 token
|
||||
if(ResponseType.token.equals(ra.responseType)) {
|
||||
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, false);
|
||||
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, false);
|
||||
String redirectUri = SaOAuth2Util.buildImplicitRedirectUri(ra.redirectUri, at.accessToken, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
// 默认返回
|
||||
throw new SaOAuth2Exception("无效response_type: " + ra.responseType);
|
||||
|
||||
// 默认返回
|
||||
throw new SaOAuth2Exception("无效response_type: " + ra.responseType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Code授权码 获取 Access-Token
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
* Code授权码 获取 Access-Token
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object token(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
// 获取参数
|
||||
String code = req.getParamNotNull(Param.code);
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
// 获取参数
|
||||
String code = req.getParamNotNull(Param.code);
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String redirectUri = req.getParam(Param.redirect_uri);
|
||||
String redirectUri = req.getParam(Param.redirect_uri);
|
||||
|
||||
// 校验参数
|
||||
SaOAuth2Util.checkGainTokenParam(code, clientId, clientSecret, redirectUri);
|
||||
|
||||
// 构建 Access-Token
|
||||
// 构建 Access-Token
|
||||
AccessTokenModel token = SaOAuth2Util.generateAccessToken(code);
|
||||
|
||||
// 返回
|
||||
return SaResult.data(token.toLineMap());
|
||||
|
||||
// 返回
|
||||
return SaResult.data(token.toLineMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh-Token 刷新 Access-Token
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
* Refresh-Token 刷新 Access-Token
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object refreshToken(SaRequest req) {
|
||||
// 获取参数
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String refreshToken = req.getParamNotNull(Param.refresh_token);
|
||||
|
||||
// 校验参数
|
||||
|
||||
// 校验参数
|
||||
SaOAuth2Util.checkRefreshTokenParam(clientId, clientSecret, refreshToken);
|
||||
|
||||
// 获取新Token返回
|
||||
// 获取新Token返回
|
||||
Object data = SaOAuth2Util.refreshAccessToken(refreshToken).toLineMap();
|
||||
return SaResult.data(data);
|
||||
return SaResult.data(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 回收 Access-Token
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
* 回收 Access-Token
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object revokeToken(SaRequest req) {
|
||||
// 获取参数
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String accessToken = req.getParamNotNull(Param.access_token);
|
||||
|
||||
|
||||
// 如果 Access-Token 不存在,直接返回
|
||||
if(SaOAuth2Util.getAccessToken(accessToken) == null) {
|
||||
return SaResult.ok("access_token不存在:" + accessToken);
|
||||
}
|
||||
|
||||
// 校验参数
|
||||
|
||||
// 校验参数
|
||||
SaOAuth2Util.checkAccessTokenParam(clientId, clientSecret, accessToken);
|
||||
|
||||
// 获取新Token返回
|
||||
// 获取新Token返回
|
||||
SaOAuth2Util.revokeAccessToken(accessToken);
|
||||
return SaResult.ok();
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* doLogin 登录接口
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
* doLogin 登录接口
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object doLogin(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
return cfg.doLoginHandle.apply(req.getParamNotNull(Param.name), req.getParamNotNull("pwd"));
|
||||
}
|
||||
|
||||
/**
|
||||
* doConfirm 确认授权接口
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
* doConfirm 确认授权接口
|
||||
* @param req 请求对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object doConfirm(SaRequest req) {
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
@ -223,68 +223,71 @@ public class SaOAuth2Handle {
|
||||
SaOAuth2Util.saveGrantScope(clientId, loginId, scope);
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 模式三:密码式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
* 模式三:密码式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object password(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 1、获取请求参数
|
||||
|
||||
// 1、获取请求参数
|
||||
String username = req.getParamNotNull(Param.username);
|
||||
String password = req.getParamNotNull(Param.password);
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
|
||||
|
||||
// 2、校验client_id
|
||||
SaOAuth2Util.checkClientModel(clientId);
|
||||
|
||||
// 3、防止因前端误传token造成逻辑干扰
|
||||
// 3、防止因前端误传token造成逻辑干扰
|
||||
SaHolder.getStorage().set(StpUtil.stpLogic.splicingKeyJustCreatedSave(), "no-token");
|
||||
|
||||
|
||||
// 4、调用API 开始登录,如果没能成功登录,则直接退出
|
||||
Object retObj = cfg.doLoginHandle.apply(username, password);
|
||||
Object retObj = cfg.doLoginHandle.apply(username, password);
|
||||
if(StpUtil.isLogin() == false) {
|
||||
return retObj;
|
||||
}
|
||||
|
||||
// 5、构建 ra对象
|
||||
|
||||
// 5、构建 ra对象
|
||||
RequestAuthModel ra = new RequestAuthModel();
|
||||
ra.clientId = clientId;
|
||||
ra.loginId = StpUtil.getLoginId();
|
||||
ra.scope = req.getParam(Param.scope, "");
|
||||
|
||||
// 6、生成 Access-Token
|
||||
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true);
|
||||
|
||||
// 7、返回 Access-Token
|
||||
ra.loginId = StpUtil.getLoginId();
|
||||
ra.scope = req.getParam(Param.scope, "");
|
||||
|
||||
// 6、生成 Access-Token
|
||||
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true);
|
||||
|
||||
// 7、返回 Access-Token
|
||||
return SaResult.data(at.toLineMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* 模式四:凭证式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
* 模式四:凭证式
|
||||
* @param req 请求对象
|
||||
* @param res 响应对象
|
||||
* @param cfg 配置对象
|
||||
* @return 处理结果
|
||||
*/
|
||||
public static Object clientToken(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
// 获取参数
|
||||
|
||||
// 获取参数
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
String clientSecret = req.getParamNotNull(Param.client_secret);
|
||||
String scope = req.getParam(Param.scope);
|
||||
|
||||
|
||||
//校验 ClientScope
|
||||
SaOAuth2Util.checkContract(clientId, scope);
|
||||
|
||||
// 校验 ClientSecret
|
||||
SaOAuth2Util.checkClientSecret(clientId, clientSecret);
|
||||
|
||||
|
||||
// 返回 Client-Token
|
||||
ClientTokenModel ct = SaOAuth2Util.generateClientToken(clientId, scope);
|
||||
|
||||
|
||||
// 返回 Client-Token
|
||||
return SaResult.data(ct.toLineMap());
|
||||
return SaResult.data(ct.toLineMap());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user