mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-07-15 14:04:36 +08:00
重构代码:OAuth2 授权模式开放由全局配置和Client单独配置共同设定
This commit is contained in:
parent
ebec86f0de
commit
e2463b7e03
@ -21,7 +21,8 @@ public class SaOAuth2TemplateImpl extends SaOAuth2Template {
|
|||||||
.setClientId("10001")
|
.setClientId("10001")
|
||||||
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee")
|
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee")
|
||||||
.setAllowUrl("*")
|
.setAllowUrl("*")
|
||||||
.setContractScope("userinfo");
|
.setContractScope("userinfo")
|
||||||
|
.setIsAutoMode(true);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -16,19 +16,15 @@ public class SaOAuth2Config implements Serializable {
|
|||||||
private static final long serialVersionUID = -6541180061782004705L;
|
private static final long serialVersionUID = -6541180061782004705L;
|
||||||
|
|
||||||
/** 是否打开模式:授权码(Authorization Code) */
|
/** 是否打开模式:授权码(Authorization Code) */
|
||||||
@Deprecated
|
|
||||||
public Boolean isCode = true;
|
public Boolean isCode = true;
|
||||||
|
|
||||||
/** 是否打开模式:隐藏式(Implicit) */
|
/** 是否打开模式:隐藏式(Implicit) */
|
||||||
@Deprecated
|
|
||||||
public Boolean isImplicit = false;
|
public Boolean isImplicit = false;
|
||||||
|
|
||||||
/** 是否打开模式:密码式(Password) */
|
/** 是否打开模式:密码式(Password) */
|
||||||
@Deprecated
|
|
||||||
public Boolean isPassword = false;
|
public Boolean isPassword = false;
|
||||||
|
|
||||||
/** 是否打开模式:凭证式(Client Credentials) */
|
/** 是否打开模式:凭证式(Client Credentials) */
|
||||||
@Deprecated
|
|
||||||
public Boolean isClient = false;
|
public Boolean isClient = false;
|
||||||
|
|
||||||
/** 是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token */
|
/** 是否在每次 Refresh-Token 刷新 Access-Token 时,产生一个新的 Refresh-Token */
|
||||||
|
@ -14,6 +14,7 @@ import cn.dev33.satoken.oauth2.model.AccessTokenModel;
|
|||||||
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
|
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
|
||||||
import cn.dev33.satoken.oauth2.model.CodeModel;
|
import cn.dev33.satoken.oauth2.model.CodeModel;
|
||||||
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
|
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
|
||||||
|
import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import cn.dev33.satoken.util.SaResult;
|
import cn.dev33.satoken.util.SaResult;
|
||||||
|
|
||||||
@ -35,16 +36,17 @@ public class SaOAuth2Handle {
|
|||||||
SaResponse res = SaHolder.getResponse();
|
SaResponse res = SaHolder.getResponse();
|
||||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||||
|
|
||||||
//读取client_id,此参数在所有模式中必填
|
|
||||||
String clientId = req.getParamNotNull(Param.client_id);
|
|
||||||
|
|
||||||
// ------------------ 路由分发 ------------------
|
// ------------------ 路由分发 ------------------
|
||||||
|
|
||||||
// 模式一:Code授权码
|
// 模式一:Code授权码
|
||||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.code) && (SaOAuth2Util.supportType(clientId,GrantType.authorization_code) || cfg.isCode)) {
|
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.code)) {
|
||||||
return authorize(req, res, cfg);
|
SaClientModel cm = currClientModel();
|
||||||
|
if(cfg.isCode && (cm.isCode || cm.isAutoMode)) {
|
||||||
|
return authorize(req, res, cfg);
|
||||||
|
}
|
||||||
|
throw new SaOAuth2Exception("暂未开放的授权模式");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code授权码 获取 Access-Token
|
// Code授权码 获取 Access-Token
|
||||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.authorization_code)) {
|
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.authorization_code)) {
|
||||||
return token(req, res, cfg);
|
return token(req, res, cfg);
|
||||||
@ -71,18 +73,31 @@ public class SaOAuth2Handle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 模式二:隐藏式
|
// 模式二:隐藏式
|
||||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.token) && (SaOAuth2Util.supportType(clientId,GrantType.implicit) || cfg.isImplicit)) {
|
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.token)) {
|
||||||
return authorize(req, res, cfg);
|
SaClientModel cm = currClientModel();
|
||||||
|
if(cfg.isImplicit && (cm.isImplicit || cm.isAutoMode)) {
|
||||||
|
return authorize(req, res, cfg);
|
||||||
|
}
|
||||||
|
throw new SaOAuth2Exception("暂未开放的授权模式");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模式三:密码式
|
// 模式三:密码式
|
||||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.password) && (SaOAuth2Util.supportType(clientId,GrantType.password) || cfg.isPassword)) {
|
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.password)) {
|
||||||
return password(req, res, cfg);
|
SaClientModel cm = currClientModel();
|
||||||
|
if(cfg.isPassword && (cm.isPassword || cm.isAutoMode)) {
|
||||||
|
return password(req, res, cfg);
|
||||||
|
}
|
||||||
|
throw new SaOAuth2Exception("暂未开放的授权模式");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模式四:凭证式
|
// 模式四:凭证式
|
||||||
if(req.isPath(Api.client_token) && req.isParam(Param.grant_type, GrantType.client_credentials) && (SaOAuth2Util.supportType(clientId,GrantType.client_credentials) || cfg.isClient)) {
|
if(req.isPath(Api.client_token) && req.isParam(Param.grant_type, GrantType.client_credentials)) {
|
||||||
return clientToken(req, res, cfg);
|
SaClientModel cm = currClientModel();
|
||||||
|
if(cfg.isClient && (cm.isClient || cm.isAutoMode)) {
|
||||||
|
return clientToken(req, res, cfg);
|
||||||
|
}
|
||||||
|
throw new SaOAuth2Exception("暂未开放的授权模式");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认返回
|
// 默认返回
|
||||||
@ -97,7 +112,7 @@ public class SaOAuth2Handle {
|
|||||||
* @return 处理结果
|
* @return 处理结果
|
||||||
*/
|
*/
|
||||||
public static Object authorize(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
public static Object authorize(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||||
|
|
||||||
// 1、如果尚未登录, 则先去登录
|
// 1、如果尚未登录, 则先去登录
|
||||||
if(StpUtil.isLogin() == false) {
|
if(StpUtil.isLogin() == false) {
|
||||||
return cfg.notLoginView.get();
|
return cfg.notLoginView.get();
|
||||||
@ -125,6 +140,7 @@ public class SaOAuth2Handle {
|
|||||||
String redirectUri = SaOAuth2Util.buildRedirectUri(ra.redirectUri, codeModel.code, ra.state);
|
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)) {
|
if(ResponseType.token.equals(ra.responseType)) {
|
||||||
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, false);
|
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, false);
|
||||||
@ -296,4 +312,13 @@ public class SaOAuth2Handle {
|
|||||||
return SaResult.data(ct.toLineMap());
|
return SaResult.data(ct.toLineMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据当前请求提交的 client_id 参数获取 SaClientModel 对象
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static SaClientModel currClientModel() {
|
||||||
|
String clientId = SaHolder.getRequest().getParam(Param.client_id);
|
||||||
|
return SaOAuth2Util.checkClientModel(clientId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
package cn.dev33.satoken.oauth2.logic;
|
package cn.dev33.satoken.oauth2.logic;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import cn.dev33.satoken.SaManager;
|
import cn.dev33.satoken.SaManager;
|
||||||
import cn.dev33.satoken.context.model.SaRequest;
|
import cn.dev33.satoken.context.model.SaRequest;
|
||||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||||
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
|
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
|
||||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.Param;
|
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.Param;
|
||||||
import cn.dev33.satoken.oauth2.model.*;
|
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
|
||||||
|
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
|
||||||
|
import cn.dev33.satoken.oauth2.model.CodeModel;
|
||||||
|
import cn.dev33.satoken.oauth2.model.RefreshTokenModel;
|
||||||
|
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
|
||||||
|
import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||||
import cn.dev33.satoken.strategy.SaStrategy;
|
import cn.dev33.satoken.strategy.SaStrategy;
|
||||||
import cn.dev33.satoken.util.SaFoxUtil;
|
import cn.dev33.satoken.util.SaFoxUtil;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sa-Token-OAuth2 模块 代码实现
|
* Sa-Token-OAuth2 模块 代码实现
|
||||||
* @author kong
|
* @author kong
|
||||||
@ -918,12 +922,4 @@ public class SaOAuth2Template {
|
|||||||
return SaManager.getConfig().getTokenName() + ":oauth2:grant-scope:" + clientId + ":" + loginId;
|
return SaManager.getConfig().getTokenName() + ":oauth2:grant-scope:" + clientId + ":" + loginId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查是否支持的type类型
|
|
||||||
*/
|
|
||||||
public Boolean supportType(String clientId,String type){
|
|
||||||
SaClientModel saClientModel = checkClientModel(clientId);
|
|
||||||
return Arrays.asList(saClientModel.getAllowType().split(",")).contains(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -293,16 +293,4 @@ public class SaOAuth2Util {
|
|||||||
return saOAuth2Template.getGrantScope(clientId, loginId);
|
return saOAuth2Template.getGrantScope(clientId, loginId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取:检查是否支持的授权类型
|
|
||||||
* @param clientId 应用id
|
|
||||||
* @param type 授权类型
|
|
||||||
* @return 是否
|
|
||||||
*/
|
|
||||||
public static Boolean supportType(String clientId, String type) {
|
|
||||||
return saOAuth2Template.supportType(clientId, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,22 +30,31 @@ public class SaClientModel implements Serializable {
|
|||||||
* 应用允许授权的所有URL, 多个用逗号隔开
|
* 应用允许授权的所有URL, 多个用逗号隔开
|
||||||
*/
|
*/
|
||||||
public String allowUrl;
|
public String allowUrl;
|
||||||
|
|
||||||
|
/** 此 Client 是否打开模式:授权码(Authorization Code) */
|
||||||
|
public Boolean isCode = false;
|
||||||
|
|
||||||
/**
|
/** 此 Client 是否打开模式:隐藏式(Implicit) */
|
||||||
* 应用允许授权的所有URL, 多个用逗号隔开
|
public Boolean isImplicit = false;
|
||||||
*/
|
|
||||||
public String allowType;
|
/** 此 Client 是否打开模式:密码式(Password) */
|
||||||
|
public Boolean isPassword = false;
|
||||||
|
|
||||||
|
/** 此 Client 是否打开模式:凭证式(Client Credentials) */
|
||||||
|
public Boolean isClient = false;
|
||||||
|
|
||||||
|
/** 是否自动判断开放的授权模式,此值为true时单独设置(isCode、isImplicit、isPassword、isClient)不再有效,而是跟随全局设置 */
|
||||||
|
public Boolean isAutoMode = false;
|
||||||
|
|
||||||
public SaClientModel() {
|
public SaClientModel() {
|
||||||
|
|
||||||
}
|
}
|
||||||
public SaClientModel(String clientId, String clientSecret, String contractScope, String allowUrl,String allowType) {
|
public SaClientModel(String clientId, String clientSecret, String contractScope, String allowUrl) {
|
||||||
super();
|
super();
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
this.clientSecret = clientSecret;
|
this.clientSecret = clientSecret;
|
||||||
this.contractScope = contractScope;
|
this.contractScope = contractScope;
|
||||||
this.allowUrl = allowUrl;
|
this.allowUrl = allowUrl;
|
||||||
this.allowType = allowType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,25 +122,92 @@ public class SaClientModel implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 应用允许的授权模式, 多个用逗号隔开
|
* @return 此 Client 是否打开模式:授权码(Authorization Code)
|
||||||
*/
|
*/
|
||||||
public String getAllowType() {
|
public Boolean getIsCode() {
|
||||||
return allowType;
|
return isCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param allowType 应用允许的授权模式, 多个用逗号隔开
|
* @param isCode 此 Client 是否打开模式:授权码(Authorization Code)
|
||||||
* @return 对象自身
|
* @return 对象自身
|
||||||
*/
|
*/
|
||||||
public SaClientModel setAllowType(String allowType) {
|
public SaClientModel setIsCode(Boolean isCode) {
|
||||||
this.allowType = allowType;
|
this.isCode = isCode;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 此 Client 是否打开模式:隐藏式(Implicit)
|
||||||
|
*/
|
||||||
|
public Boolean getIsImplicit() {
|
||||||
|
return isImplicit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isImplicit 此 Client 是否打开模式:隐藏式(Implicit)
|
||||||
|
* @return 对象自身
|
||||||
|
*/
|
||||||
|
public SaClientModel setIsImplicit(Boolean isImplicit) {
|
||||||
|
this.isImplicit = isImplicit;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 此 Client 是否打开模式:密码式(Password)
|
||||||
|
*/
|
||||||
|
public Boolean getIsPassword() {
|
||||||
|
return isPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isPassword 此 Client 是否打开模式:密码式(Password)
|
||||||
|
* @return 对象自身
|
||||||
|
*/
|
||||||
|
public SaClientModel setIsPassword(Boolean isPassword) {
|
||||||
|
this.isPassword = isPassword;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 此 Client 是否打开模式:凭证式(Client Credentials)
|
||||||
|
* @return 对象自身
|
||||||
|
*/
|
||||||
|
public Boolean getIsClient() {
|
||||||
|
return isClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isClient 此 Client 是否打开模式:凭证式(Client Credentials)
|
||||||
|
* @return 对象自身
|
||||||
|
*/
|
||||||
|
public SaClientModel setIsClient(Boolean isClient) {
|
||||||
|
this.isClient = isClient;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 是否自动判断开放的授权模式
|
||||||
|
*/
|
||||||
|
public Boolean getIsAutoMode() {
|
||||||
|
return isAutoMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isAutoMode 是否自动判断开放的授权模式
|
||||||
|
* @return 对象自身
|
||||||
|
*/
|
||||||
|
public SaClientModel setIsAutoMode(Boolean isAutoMode) {
|
||||||
|
this.isAutoMode = isAutoMode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SaClientModel [clientId=" + clientId + ", clientSecret=" + clientSecret + ", contractScope="
|
return "SaClientModel [clientId=" + clientId + ", clientSecret=" + clientSecret + ", contractScope="
|
||||||
+ contractScope + ", allowUrl=" + allowUrl + "]";
|
+ contractScope + ", allowUrl=" + allowUrl + ", isCode=" + isCode + ", isImplicit=" + isImplicit
|
||||||
|
+ ", isPassword=" + isPassword + ", isClient=" + isClient + ", isAutoMode=" + isAutoMode + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user