mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-04-05 17:37:53 +08:00
重构代码:OAuth2 授权模式开放由全局配置和Client单独配置共同设定
This commit is contained in:
parent
ebec86f0de
commit
e2463b7e03
@ -21,7 +21,8 @@ public class SaOAuth2TemplateImpl extends SaOAuth2Template {
|
||||
.setClientId("10001")
|
||||
.setClientSecret("aaaa-bbbb-cccc-dddd-eeee")
|
||||
.setAllowUrl("*")
|
||||
.setContractScope("userinfo");
|
||||
.setContractScope("userinfo")
|
||||
.setIsAutoMode(true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -16,19 +16,15 @@ public class SaOAuth2Config implements Serializable {
|
||||
private static final long serialVersionUID = -6541180061782004705L;
|
||||
|
||||
/** 是否打开模式:授权码(Authorization Code) */
|
||||
@Deprecated
|
||||
public Boolean isCode = true;
|
||||
|
||||
/** 是否打开模式:隐藏式(Implicit) */
|
||||
@Deprecated
|
||||
public Boolean isImplicit = false;
|
||||
|
||||
/** 是否打开模式:密码式(Password) */
|
||||
@Deprecated
|
||||
public Boolean isPassword = false;
|
||||
|
||||
/** 是否打开模式:凭证式(Client Credentials) */
|
||||
@Deprecated
|
||||
public Boolean isClient = false;
|
||||
|
||||
/** 是否在每次 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.CodeModel;
|
||||
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
|
||||
import cn.dev33.satoken.oauth2.model.SaClientModel;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
@ -35,16 +36,17 @@ public class SaOAuth2Handle {
|
||||
SaResponse res = SaHolder.getResponse();
|
||||
SaOAuth2Config cfg = SaOAuth2Manager.getConfig();
|
||||
|
||||
//读取client_id,此参数在所有模式中必填
|
||||
String clientId = req.getParamNotNull(Param.client_id);
|
||||
|
||||
// ------------------ 路由分发 ------------------
|
||||
|
||||
// 模式一:Code授权码
|
||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.code) && (SaOAuth2Util.supportType(clientId,GrantType.authorization_code) || cfg.isCode)) {
|
||||
return authorize(req, res, cfg);
|
||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.code)) {
|
||||
SaClientModel cm = currClientModel();
|
||||
if(cfg.isCode && (cm.isCode || cm.isAutoMode)) {
|
||||
return authorize(req, res, cfg);
|
||||
}
|
||||
throw new SaOAuth2Exception("暂未开放的授权模式");
|
||||
}
|
||||
|
||||
|
||||
// Code授权码 获取 Access-Token
|
||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.authorization_code)) {
|
||||
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)) {
|
||||
return authorize(req, res, cfg);
|
||||
if(req.isPath(Api.authorize) && req.isParam(Param.response_type, ResponseType.token)) {
|
||||
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)) {
|
||||
return password(req, res, cfg);
|
||||
if(req.isPath(Api.token) && req.isParam(Param.grant_type, GrantType.password)) {
|
||||
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)) {
|
||||
return clientToken(req, res, cfg);
|
||||
if(req.isPath(Api.client_token) && req.isParam(Param.grant_type, GrantType.client_credentials)) {
|
||||
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 处理结果
|
||||
*/
|
||||
public static Object authorize(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
|
||||
|
||||
// 1、如果尚未登录, 则先去登录
|
||||
if(StpUtil.isLogin() == false) {
|
||||
return cfg.notLoginView.get();
|
||||
@ -125,6 +140,7 @@ public class SaOAuth2Handle {
|
||||
String redirectUri = SaOAuth2Util.buildRedirectUri(ra.redirectUri, codeModel.code, ra.state);
|
||||
return res.redirect(redirectUri);
|
||||
}
|
||||
|
||||
// 如果是 隐藏式,则:开始重定向授权,下放 token
|
||||
if(ResponseType.token.equals(ra.responseType)) {
|
||||
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, false);
|
||||
@ -296,4 +312,13 @@ public class SaOAuth2Handle {
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
|
||||
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.util.SaFoxUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sa-Token-OAuth2 模块 代码实现
|
||||
* @author kong
|
||||
@ -918,12 +922,4 @@ public class SaOAuth2Template {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取:检查是否支持的授权类型
|
||||
* @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, 多个用逗号隔开
|
||||
*/
|
||||
public String allowUrl;
|
||||
|
||||
/** 此 Client 是否打开模式:授权码(Authorization Code) */
|
||||
public Boolean isCode = false;
|
||||
|
||||
/**
|
||||
* 应用允许授权的所有URL, 多个用逗号隔开
|
||||
*/
|
||||
public String allowType;
|
||||
/** 此 Client 是否打开模式:隐藏式(Implicit) */
|
||||
public Boolean isImplicit = false;
|
||||
|
||||
/** 此 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(String clientId, String clientSecret, String contractScope, String allowUrl,String allowType) {
|
||||
public SaClientModel(String clientId, String clientSecret, String contractScope, String allowUrl) {
|
||||
super();
|
||||
this.clientId = clientId;
|
||||
this.clientSecret = clientSecret;
|
||||
this.contractScope = contractScope;
|
||||
this.allowUrl = allowUrl;
|
||||
this.allowType = allowType;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,25 +122,92 @@ public class SaClientModel implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 应用允许的授权模式, 多个用逗号隔开
|
||||
* @return 此 Client 是否打开模式:授权码(Authorization Code)
|
||||
*/
|
||||
public String getAllowType() {
|
||||
return allowType;
|
||||
public Boolean getIsCode() {
|
||||
return isCode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param allowType 应用允许的授权模式, 多个用逗号隔开
|
||||
* @return 对象自身
|
||||
* @param isCode 此 Client 是否打开模式:授权码(Authorization Code)
|
||||
* @return 对象自身
|
||||
*/
|
||||
public SaClientModel setAllowType(String allowType) {
|
||||
this.allowType = allowType;
|
||||
public SaClientModel setIsCode(Boolean isCode) {
|
||||
this.isCode = isCode;
|
||||
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
|
||||
public String toString() {
|
||||
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