重构异常状态码机制

This commit is contained in:
click33
2022-10-31 02:00:38 +08:00
parent f21b6d8b07
commit d2665036a2
56 changed files with 832 additions and 229 deletions

View File

@@ -0,0 +1,98 @@
package cn.dev33.satoken.oauth2.error;
/**
* 定义 sa-token-oauth2 所有异常细分状态码
*
* @author kong
* @since: 2022-10-31
*/
public interface SaOAuth2ErrorCode {
/** client_id 不可为空 */
public static final int CODE_30101 = 30101;
/** scope 不可为空 */
public static final int CODE_30102 = 30102;
/** redirect_uri 不可为空 */
public static final int CODE_30103 = 30103;
/** LoginId 不可为空 */
public static final int CODE_30104 = 30104;
/** 无效client_id */
public static final int CODE_30105 = 30105;
/** 无效access_token */
public static final int CODE_30106 = 30106;
/** 无效 client_token */
public static final int CODE_30107 = 30107;
/** Access-Token 不具备指定的 Scope */
public static final int CODE_30108 = 30108;
/** Client-Token 不具备指定的 Scope */
public static final int CODE_30109 = 30109;
/** 无效 code 码 */
public static final int CODE_30110 = 30110;
/** 无效 Refresh-Token */
public static final int CODE_30111 = 30111;
/** 请求的Scope暂未签约 */
public static final int CODE_30112 = 30112;
/** 无效redirect_url */
public static final int CODE_30113 = 30113;
/** 非法redirect_url */
public static final int CODE_30114 = 30114;
/** 无效client_secret */
public static final int CODE_30115 = 30115;
/** 请求的Scope暂未签约 */
public static final int CODE_30116 = 30116;
/** 无效code */
public static final int CODE_30117 = 30117;
/** 无效client_id */
public static final int CODE_30118 = 30118;
/** 无效client_secret */
public static final int CODE_30119 = 30119;
/** 无效redirect_uri */
public static final int CODE_30120 = 30120;
/** 无效refresh_token */
public static final int CODE_30121 = 30121;
/** 无效client_id */
public static final int CODE_30122 = 30122;
/** 无效client_secret */
public static final int CODE_30123 = 30123;
/** 无效client_id */
public static final int CODE_30124 = 30124;
/** 无效response_type */
public static final int CODE_30125 = 30125;
/** 暂未开放授权码模式 */
public static final int CODE_30131 = 30131;
/** 暂未开放隐藏式模式 */
public static final int CODE_30132 = 30132;
/** 暂未开放密码式模式 */
public static final int CODE_30133 = 30133;
/** 暂未开放凭证式模式 */
public static final int CODE_30134 = 30134;
}

View File

@@ -26,10 +26,11 @@ public class SaOAuth2Exception extends SaTokenException {
* 如果flag==true则抛出message异常
* @param flag 标记
* @param message 异常信息
* @param code 异常细分码
*/
public static void throwBy(boolean flag, String message) {
public static void throwBy(boolean flag, String message, int code) {
if(flag) {
throw new SaOAuth2Exception(message);
throw new SaOAuth2Exception(message).setCode(code);
}
}

View File

@@ -5,6 +5,7 @@ import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
import cn.dev33.satoken.oauth2.error.SaOAuth2ErrorCode;
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.Api;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.GrantType;
@@ -44,7 +45,7 @@ public class SaOAuth2Handle {
if(cfg.getIsCode() && (cm.isCode || cm.isAutoMode)) {
return authorize(req, res, cfg);
}
throw new SaOAuth2Exception("暂未开放的授权模式");
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30131);
}
// Code授权码 获取 Access-Token
@@ -78,7 +79,7 @@ public class SaOAuth2Handle {
if(cfg.getIsImplicit() && (cm.isImplicit || cm.isAutoMode)) {
return authorize(req, res, cfg);
}
throw new SaOAuth2Exception("暂未开放的授权模式");
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30132);
}
// 模式三:密码式
@@ -87,7 +88,7 @@ public class SaOAuth2Handle {
if(cfg.getIsPassword() && (cm.isPassword || cm.isAutoMode)) {
return password(req, res, cfg);
}
throw new SaOAuth2Exception("暂未开放的授权模式");
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30133);
}
// 模式四:凭证式
@@ -96,7 +97,7 @@ public class SaOAuth2Handle {
if(cfg.getIsClient() && (cm.isClient || cm.isAutoMode)) {
return clientToken(req, res, cfg);
}
throw new SaOAuth2Exception("暂未开放的授权模式");
throw new SaOAuth2Exception("暂未开放的授权模式").setCode(SaOAuth2ErrorCode.CODE_30134);
}
// 默认返回
@@ -148,7 +149,7 @@ public class SaOAuth2Handle {
}
// 默认返回
throw new SaOAuth2Exception("无效response_type: " + ra.responseType);
throw new SaOAuth2Exception("无效response_type: " + ra.responseType).setCode(SaOAuth2ErrorCode.CODE_30125);
}
/**

View File

@@ -5,6 +5,7 @@ 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.error.SaOAuth2ErrorCode;
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.Param;
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
@@ -51,7 +52,7 @@ public class SaOAuth2Template {
public SaClientModel checkClientModel(String clientId) {
SaClientModel clientModel = getClientModel(clientId);
if(clientModel == null) {
throw new SaOAuth2Exception("无效client_id: " + clientId);
throw new SaOAuth2Exception("无效client_id: " + clientId).setCode(SaOAuth2ErrorCode.CODE_30105);
}
return clientModel;
}
@@ -62,7 +63,7 @@ public class SaOAuth2Template {
*/
public AccessTokenModel checkAccessToken(String accessToken) {
AccessTokenModel at = getAccessToken(accessToken);
SaOAuth2Exception.throwBy(at == null, "无效access_token" + accessToken);
SaOAuth2Exception.throwBy(at == null, "无效access_token" + accessToken, SaOAuth2ErrorCode.CODE_30106);
return at;
}
/**
@@ -72,7 +73,7 @@ public class SaOAuth2Template {
*/
public ClientTokenModel checkClientToken(String clientToken) {
ClientTokenModel ct = getClientToken(clientToken);
SaOAuth2Exception.throwBy(ct == null, "无效client_token" + ct);
SaOAuth2Exception.throwBy(ct == null, "无效client_token" + ct, SaOAuth2ErrorCode.CODE_30107);
return ct;
}
/**
@@ -95,7 +96,7 @@ public class SaOAuth2Template {
AccessTokenModel at = checkAccessToken(accessToken);
List<String> scopeList = SaFoxUtil.convertStringToList(at.scope);
for (String scope : scopes) {
SaOAuth2Exception.throwBy(scopeList.contains(scope) == false, "该 Access-Token 不具备 Scope" + scope);
SaOAuth2Exception.throwBy(scopeList.contains(scope) == false, "该 Access-Token 不具备 Scope" + scope, SaOAuth2ErrorCode.CODE_30108);
}
}
/**
@@ -110,7 +111,7 @@ public class SaOAuth2Template {
ClientTokenModel ct = checkClientToken(clientToken);
List<String> scopeList = SaFoxUtil.convertStringToList(ct.scope);
for (String scope : scopes) {
SaOAuth2Exception.throwBy(scopeList.contains(scope) == false, "该 Client-Token 不具备 Scope" + scope);
SaOAuth2Exception.throwBy(scopeList.contains(scope) == false, "该 Client-Token 不具备 Scope" + scope, SaOAuth2ErrorCode.CODE_30109);
}
}
@@ -161,7 +162,7 @@ public class SaOAuth2Template {
// 1、先校验
CodeModel cm = getCode(code);
SaOAuth2Exception.throwBy(cm == null, "无效code");
SaOAuth2Exception.throwBy(cm == null, "无效code", SaOAuth2ErrorCode.CODE_30110);
// 2、删除旧Token
deleteAccessToken(getAccessTokenValue(cm.clientId, cm.loginId));
@@ -195,7 +196,7 @@ public class SaOAuth2Template {
// 获取 Refresh-Token 信息
RefreshTokenModel rt = getRefreshToken(refreshToken);
SaOAuth2Exception.throwBy(rt == null, "无效refresh_token: " + refreshToken);
SaOAuth2Exception.throwBy(rt == null, "无效refresh_token: " + refreshToken, SaOAuth2ErrorCode.CODE_30111);
// 如果配置了[每次刷新产生新的Refresh-Token]
if(checkClientModel(rt.clientId).getIsNewRefresh()) {
@@ -359,7 +360,7 @@ public class SaOAuth2Template {
List<String> clientScopeList = SaFoxUtil.convertStringToList(checkClientModel(clientId).contractScope);
List<String> scopelist = SaFoxUtil.convertStringToList(scope);
if(clientScopeList.containsAll(scopelist) == false) {
throw new SaOAuth2Exception("请求的Scope暂未签约");
throw new SaOAuth2Exception("请求的Scope暂未签约").setCode(SaOAuth2ErrorCode.CODE_30112);
}
}
/**
@@ -370,7 +371,7 @@ public class SaOAuth2Template {
public void checkRightUrl(String clientId, String url) {
// 1、是否是一个有效的url
if(SaFoxUtil.isUrl(url) == false) {
throw new SaOAuth2Exception("无效redirect_url" + url);
throw new SaOAuth2Exception("无效redirect_url" + url).setCode(SaOAuth2ErrorCode.CODE_30113);
}
// 2、截取掉?后面的部分
@@ -382,7 +383,7 @@ public class SaOAuth2Template {
// 3、是否在[允许地址列表]之中
List<String> allowList = SaFoxUtil.convertStringToList(checkClientModel(clientId).allowUrl);
if(SaStrategy.me.hasElement.apply(allowList, url) == false) {
throw new SaOAuth2Exception("非法redirect_url" + url);
throw new SaOAuth2Exception("非法redirect_url" + url).setCode(SaOAuth2ErrorCode.CODE_30114);
}
}
/**
@@ -393,7 +394,8 @@ public class SaOAuth2Template {
*/
public SaClientModel checkClientSecret(String clientId, String clientSecret) {
SaClientModel cm = checkClientModel(clientId);
SaOAuth2Exception.throwBy(cm.clientSecret == null || cm.clientSecret.equals(clientSecret) == false, "无效client_secret: " + clientSecret);
SaOAuth2Exception.throwBy(cm.clientSecret == null || cm.clientSecret.equals(clientSecret) == false,
"无效client_secret: " + clientSecret, SaOAuth2ErrorCode.CODE_30115);
return cm;
}
/**
@@ -410,7 +412,7 @@ public class SaOAuth2Template {
List<String> clientScopeList = SaFoxUtil.convertStringToList(cm.contractScope);
List<String> scopelist = SaFoxUtil.convertStringToList(scopes);
if(clientScopeList.containsAll(scopelist) == false) {
throw new SaOAuth2Exception("请求的Scope暂未签约");
throw new SaOAuth2Exception("请求的Scope暂未签约").setCode(SaOAuth2ErrorCode.CODE_30116);
}
// 返回数据
return cm;
@@ -427,18 +429,18 @@ public class SaOAuth2Template {
// 校验Code是否存在
CodeModel cm = getCode(code);
SaOAuth2Exception.throwBy(cm == null, "无效code: " + code);
SaOAuth2Exception.throwBy(cm == null, "无效code: " + code, SaOAuth2ErrorCode.CODE_30117);
// 校验ClientId是否一致
SaOAuth2Exception.throwBy(cm.clientId.equals(clientId) == false, "无效client_id: " + clientId);
SaOAuth2Exception.throwBy(cm.clientId.equals(clientId) == false, "无效client_id: " + clientId, SaOAuth2ErrorCode.CODE_30118);
// 校验Secret是否正确
String dbSecret = checkClientModel(clientId).clientSecret;
SaOAuth2Exception.throwBy(dbSecret == null || dbSecret.equals(clientSecret) == false, "无效client_secret: " + clientSecret);
SaOAuth2Exception.throwBy(dbSecret == null || dbSecret.equals(clientSecret) == false, "无效client_secret: " + clientSecret, SaOAuth2ErrorCode.CODE_30119);
// 如果提供了redirectUri则校验其是否与请求Code时提供的一致
if(SaFoxUtil.isEmpty(redirectUri) == false) {
SaOAuth2Exception.throwBy(redirectUri.equals(cm.redirectUri) == false, "无效redirect_uri: " + redirectUri);
SaOAuth2Exception.throwBy(redirectUri.equals(cm.redirectUri) == false, "无效redirect_uri: " + redirectUri, SaOAuth2ErrorCode.CODE_30120);
}
// 返回CodeMdoel
@@ -455,14 +457,14 @@ public class SaOAuth2Template {
// 校验Refresh-Token是否存在
RefreshTokenModel rt = getRefreshToken(refreshToken);
SaOAuth2Exception.throwBy(rt == null, "无效refresh_token: " + refreshToken);
SaOAuth2Exception.throwBy(rt == null, "无效refresh_token: " + refreshToken, SaOAuth2ErrorCode.CODE_30121);
// 校验ClientId是否一致
SaOAuth2Exception.throwBy(rt.clientId.equals(clientId) == false, "无效client_id: " + clientId);
SaOAuth2Exception.throwBy(rt.clientId.equals(clientId) == false, "无效client_id: " + clientId, SaOAuth2ErrorCode.CODE_30122);
// 校验Secret是否正确
String dbSecret = checkClientModel(clientId).clientSecret;
SaOAuth2Exception.throwBy(dbSecret == null || dbSecret.equals(clientSecret) == false, "无效client_secret: " + clientSecret);
SaOAuth2Exception.throwBy(dbSecret == null || dbSecret.equals(clientSecret) == false, "无效client_secret: " + clientSecret, SaOAuth2ErrorCode.CODE_30123);
// 返回Refresh-Token
return rt;
@@ -476,7 +478,7 @@ public class SaOAuth2Template {
*/
public AccessTokenModel checkAccessTokenParam(String clientId, String clientSecret, String accessToken) {
AccessTokenModel at = checkAccessToken(accessToken);
SaOAuth2Exception.throwBy(at.clientId.equals(clientId) == false, "无效client_id" + clientId);
SaOAuth2Exception.throwBy(at.clientId.equals(clientId) == false, "无效client_id" + clientId, SaOAuth2ErrorCode.CODE_30124);
checkClientSecret(clientId, clientSecret);
return at;
}

View File

@@ -2,7 +2,8 @@ package cn.dev33.satoken.oauth2.model;
import java.io.Serializable;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.oauth2.error.SaOAuth2ErrorCode;
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
import cn.dev33.satoken.util.SaFoxUtil;
/**
@@ -147,16 +148,16 @@ public class RequestAuthModel implements Serializable {
*/
public RequestAuthModel checkModel() {
if(SaFoxUtil.isEmpty(clientId)) {
throw new SaTokenException("无效client_id");
throw new SaOAuth2Exception("client_id 不可为空").setCode(SaOAuth2ErrorCode.CODE_30101);
}
if(SaFoxUtil.isEmpty(scope)) {
throw new SaTokenException("无效scope");
throw new SaOAuth2Exception("scope 不可为空").setCode(SaOAuth2ErrorCode.CODE_30102);
}
if(SaFoxUtil.isEmpty(redirectUri)) {
throw new SaTokenException("无效redirect_uri");
throw new SaOAuth2Exception("redirect_uri 不可为空").setCode(SaOAuth2ErrorCode.CODE_30103);
}
if(SaFoxUtil.isEmpty(String.valueOf(loginId))) {
throw new SaTokenException("无效LoginId");
throw new SaOAuth2Exception("LoginId 不可为空").setCode(SaOAuth2ErrorCode.CODE_30104);
}
return this;
}