重构异常状态码机制

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

@ -10,6 +10,7 @@ import cn.dev33.satoken.context.SaTokenContextDefaultImpl;
import cn.dev33.satoken.context.second.SaTokenSecondContext;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.json.SaJsonTemplate;
import cn.dev33.satoken.json.SaJsonTemplateDefaultImpl;
@ -269,7 +270,7 @@ public class SaManager {
* (1) 从main方法里调用一次
* (2) 在自定义StpUtil类加上类似 @Component 的注解让容器启动时扫描到自动初始化
*/
throw new SaTokenException("未能获取对应StpLogictype="+ loginType);
throw new SaTokenException("未能获取对应StpLogictype="+ loginType).setCode(SaErrorCode.CODE_10002);
}
}

View File

@ -2,6 +2,7 @@ package cn.dev33.satoken.basic;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.NotBasicAuthException;
import cn.dev33.satoken.secure.SaBase64Util;
import cn.dev33.satoken.util.SaFoxUtil;
@ -24,7 +25,7 @@ public class SaBasicTemplate {
*/
public void throwNotBasicAuthException(String realm) {
SaHolder.getResponse().setStatus(401).setHeader("WWW-Authenticate", "Basic Realm=" + realm);
throw new NotBasicAuthException();
throw new NotBasicAuthException().setCode(SaErrorCode.CODE_10311);
}
/**

View File

@ -7,6 +7,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.util.SaFoxUtil;
/**
@ -15,7 +17,7 @@ import cn.dev33.satoken.util.SaFoxUtil;
* 用于手动读取配置文件初始化 SaTokenConfig 对象只有在非IOC环境下你才会用到此类
*
* @author kong
*
* @since 2022-10-30
*/
public class SaTokenConfigFactory {
@ -69,7 +71,7 @@ public class SaTokenConfigFactory {
map.put(key, prop.getProperty(key));
}
} catch (IOException e) {
throw new RuntimeException("配置文件(" + propertiesPath + ")加载失败", e);
throw new SaTokenException("配置文件(" + propertiesPath + ")加载失败", e).setCode(SaErrorCode.CODE_10021);
}
return map;
}
@ -110,7 +112,7 @@ public class SaTokenConfigFactory {
field.setAccessible(true);
field.set(obj, valueConvert);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("属性赋值出错:" + field.getName(), e);
throw new SaTokenException("属性赋值出错:" + field.getName(), e).setCode(SaErrorCode.CODE_10022);
}
}
return obj;

View File

@ -1,9 +1,10 @@
package cn.dev33.satoken.context;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaStorage;
import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.context.model.SaStorage;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.InvalidContextException;
/**
* Sa-Token 上下文处理器 [默认实现类]
@ -26,14 +27,14 @@ public class SaTokenContextDefaultImpl implements SaTokenContext {
/**
* 默认的错误提示语
*/
public static final String ERROR_MESSAGE = "初始化任何有效上下文处理器";
public static final String ERROR_MESSAGE = "能获取有效的上下文处理器";
/**
* 获取当前请求的 [Request] 对象
*/
@Override
public SaRequest getRequest() {
throw new SaTokenException(ERROR_MESSAGE);
throw new InvalidContextException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10001);
}
/**
@ -41,7 +42,7 @@ public class SaTokenContextDefaultImpl implements SaTokenContext {
*/
@Override
public SaResponse getResponse() {
throw new SaTokenException(ERROR_MESSAGE);
throw new InvalidContextException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10001);
}
/**
@ -49,7 +50,7 @@ public class SaTokenContextDefaultImpl implements SaTokenContext {
*/
@Override
public SaStorage getStorage() {
throw new SaTokenException(ERROR_MESSAGE);
throw new InvalidContextException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10001);
}
/**
@ -57,8 +58,7 @@ public class SaTokenContextDefaultImpl implements SaTokenContext {
*/
@Override
public boolean matchPath(String pattern, String path) {
throw new SaTokenException(ERROR_MESSAGE);
throw new InvalidContextException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10001);
}
}

View File

@ -3,7 +3,8 @@ package cn.dev33.satoken.context;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.context.model.SaStorage;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.InvalidContextException;
/**
* Sa-Token 上下文处理器 [ThreadLocal版本] ---- 对象存储器
@ -51,7 +52,7 @@ public class SaTokenContextForThreadLocalStorage {
public static Box getBoxNotNull() {
Box box = boxThreadLocal.get();
if(box == null) {
throw new SaTokenException("未成功初始化上下文");
throw new InvalidContextException("未能获取有效的上下文").setCode(SaErrorCode.CODE_10002);
}
return box;
};

View File

@ -5,6 +5,7 @@ import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.util.SaFoxUtil;
@ -233,10 +234,10 @@ public class SaCookie {
this.builde();
if(SaFoxUtil.isEmpty(name)) {
throw new SaTokenException("name不能为空");
throw new SaTokenException("name不能为空").setCode(SaErrorCode.CODE_12002);
}
if(value != null && value.indexOf(";") > -1) {
throw new SaTokenException("无效Value" + value);
throw new SaTokenException("无效Value" + value).setCode(SaErrorCode.CODE_12003);
}
// Set-Cookie: name=value; Max-Age=100000; Expires=Tue, 05-Oct-2021 20:28:17 GMT; Domain=localhost; Path=/; Secure; HttpOnly; SameSite=Lax

View File

@ -1,5 +1,6 @@
package cn.dev33.satoken.context.model;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.util.SaFoxUtil;
@ -65,7 +66,7 @@ public interface SaRequest {
public default String getParamNotNull(String name) {
String paramValue = getParam(name);
if(SaFoxUtil.isEmpty(paramValue)) {
throw new SaTokenException("缺少参数:" + name);
throw new SaTokenException("缺少参数:" + name).setCode(SaErrorCode.CODE_12001);
}
return paramValue;
}
@ -139,8 +140,6 @@ public interface SaRequest {
* @param path 转发地址
* @return 任意值
*/
public default Object forward(String path) {
throw new SaTokenException("No implementation");
}
public Object forward(String path);
}

View File

@ -0,0 +1,158 @@
package cn.dev33.satoken.error;
/**
* 定义所有异常细分状态码
*
* @author kong
* @since: 2022-10-30
*/
public interface SaErrorCode {
/** 代表这个异常在抛出时未指定异常细分状态码 */
public static final int CODE_UNDEFINED = -1;
// ------------
/** 未能获取有效的上下文处理器 */
public static final int CODE_10001 = 10001;
/** 未能获取有效的上下文 */
public static final int CODE_10002 = 10002;
/** JSON 转换器未实现 */
public static final int CODE_10003 = 10003;
/** 未能从全局 StpLogic 集合中找到对应 type 的 StpLogic */
public static final int CODE_10011 = 10011;
/** 指定的配置文件加载失败 */
public static final int CODE_10021 = 10021;
/** 配置文件属性无法正常读取 */
public static final int CODE_10022 = 10022;
/** 重置的侦听器集合不可以为空 */
public static final int CODE_10031 = 10031;
/** 注册的侦听器不可以为空 */
public static final int CODE_10032 = 10032;
// 1030x core模块
/** 提供的 Same-Token 是无效的 */
public static final int CODE_10301 = 10301;
/** 表示未能通过 Http Basic 认证校验 */
public static final int CODE_10311 = 10311;
/** 提供的 HttpMethod 是无效的 */
public static final int CODE_10321 = 10321;
// 1100x StpLogic
/** 未能读取到有效Token */
public static final int CODE_11001 = 11001;
/** 登录时的账号id值为空 */
public static final int CODE_11002 = 11002;
/** 更改 Token 指向的 账号Id 时账号Id值为空 */
public static final int CODE_11003 = 11003;
/** 未能读取到有效Token */
public static final int CODE_11011 = 11011;
/** Token无效 */
public static final int CODE_11012 = 11012;
/** Token已过期 */
public static final int CODE_11013 = 11013;
/** Token已被顶下线 */
public static final int CODE_11014 = 11014;
/** Token已被踢下线 */
public static final int CODE_11015 = 11015;
/** Token已临时过期 */
public static final int CODE_11016 = 11016;
/** 在未集成 sa-token-jwt 插件时调用 getExtra() 抛出异常 */
public static final int CODE_11031 = 11031;
/** 缺少指定的角色 */
public static final int CODE_11041 = 11041;
/** 缺少指定的权限 */
public static final int CODE_11051 = 11051;
/** 当前账号未通过服务封禁校验 */
public static final int CODE_11061 = 11061;
/** 提供要解禁的账号无效 */
public static final int CODE_11062 = 11062;
/** 提供要解禁的服务无效 */
public static final int CODE_11063 = 11063;
/** 提供要解禁的等级无效 */
public static final int CODE_11064 = 11064;
/** 二级认证校验未通过 */
public static final int CODE_11071 = 11071;
// ------------
/** 请求中缺少指定的参数 */
public static final int CODE_12001 = 12001;
/** 构建 Cookie 时缺少 name 参数 */
public static final int CODE_12002 = 12002;
/** 构建 Cookie 时缺少 value 参数 */
public static final int CODE_12003 = 12003;
// ------------
/** Base64 编码异常 */
public static final int CODE_12101 = 12101;
/** Base64 解码异常 */
public static final int CODE_12102 = 12102;
/** URL 编码异常 */
public static final int CODE_12103 = 12103;
/** URL 解码异常 */
public static final int CODE_12104 = 12104;
/** md5 加密异常 */
public static final int CODE_12111 = 12111;
/** sha1 加密异常 */
public static final int CODE_12112 = 12112;
/** sha256 加密异常 */
public static final int CODE_12113 = 12113;
/** AES 加密异常 */
public static final int CODE_12114 = 12114;
/** AES 解密异常 */
public static final int CODE_12115 = 12115;
/** RSA 公钥加密异常 */
public static final int CODE_12116 = 12116;
/** RSA 私钥加密异常 */
public static final int CODE_12117 = 12117;
/** RSA 公钥解密异常 */
public static final int CODE_12118 = 12118;
/** RSA 私钥解密异常 */
public static final int CODE_12119 = 12119;
}

View File

@ -0,0 +1,24 @@
package cn.dev33.satoken.exception;
/**
* 一个异常代表未能获取有效的上下文
*
* @author kong
* @since 2022-10-29
*/
public class InvalidContextException extends SaTokenException {
/**
* 序列化版本号
*/
private static final long serialVersionUID = 6806129545290130144L;
/**
* 一个异常代表未能获取有效的上下文
* @param message 异常描述
*/
public InvalidContextException(String message) {
super(message);
}
}

View File

@ -0,0 +1,25 @@
package cn.dev33.satoken.exception;
/**
* 一个异常代表组件或方法未被提供有效的实现
*
* @author kong
* @since 2022-10-30
*/
public class NotImplException extends SaTokenException {
/**
* 序列化版本号
*/
private static final long serialVersionUID = 6806129545290130144L;
/**
* 一个异常代表组件或方法未被提供有效的实现
* @param message 异常描述
*/
public NotImplException(String message) {
super(message);
}
}

View File

@ -0,0 +1,24 @@
package cn.dev33.satoken.exception;
/**
* 一个异常代表不是 Web 上下文
*
* @author kong
* @since 2022-10-29
*/
public class NotWebContextException extends SaTokenException {
/**
* 序列化版本号
*/
private static final long serialVersionUID = 6806129545290130144L;
/**
* 一个异常代表不是 Web 上下文
* @param message 异常描述
*/
public NotWebContextException(String message) {
super(message);
}
}

View File

@ -1,14 +0,0 @@
package cn.dev33.satoken.exception;
/**
* 定义所有异常细分状态码
*
* @author kong
* @since: 2022-4-25
*/
public class SaExceptionCode {
/** 代表这个异常在抛出时未指定异常细分状态码 */
public static final int CODE_UNDEFINED = -1;
}

View File

@ -1,5 +1,6 @@
package cn.dev33.satoken.exception;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.util.SaFoxUtil;
/**
@ -19,7 +20,7 @@ public class SaTokenException extends RuntimeException {
/**
* 异常细分状态码
*/
private int code = SaExceptionCode.CODE_UNDEFINED;
private int code = SaErrorCode.CODE_UNDEFINED;
/**
* 构建一个异常
@ -93,8 +94,9 @@ public class SaTokenException extends RuntimeException {
* 如果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 SaTokenException(message);
}
@ -104,10 +106,11 @@ public class SaTokenException extends RuntimeException {
* 如果value==null或者isEmpty则抛出message异常
* @param value
* @param message 异常信息
* @param code 异常细分状态码
*/
public static void throwByNull(Object value, String message) {
public static void throwByNull(Object value, String message, int code) {
if(SaFoxUtil.isEmpty(value)) {
throw new SaTokenException(message);
throw new SaTokenException(message).setCode(code);
}
}

View File

@ -2,7 +2,8 @@ package cn.dev33.satoken.json;
import java.util.Map;
import cn.dev33.satoken.exception.ApiDisabledException;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.NotImplException;
/**
* JSON 相关操作接口
@ -19,7 +20,7 @@ public class SaJsonTemplateDefaultImpl implements SaJsonTemplate {
*/
@Override
public String toJsonString(Object obj) {
throw new ApiDisabledException(ERROR_MESSAGE);
throw new NotImplException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10003);
}
/**
@ -27,7 +28,7 @@ public class SaJsonTemplateDefaultImpl implements SaJsonTemplate {
*/
@Override
public Map<String, Object> parseJsonToMap(String jsonStr) {
throw new ApiDisabledException(ERROR_MESSAGE);
throw new NotImplException(ERROR_MESSAGE).setCode(SaErrorCode.CODE_10003);
};
}

View File

@ -3,6 +3,7 @@ package cn.dev33.satoken.listener;
import java.util.ArrayList;
import java.util.List;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.stp.SaLoginModel;
@ -37,7 +38,7 @@ public class SaTokenEventCenter {
*/
public static void setListenerList(List<SaTokenListener> listenerList) {
if(listenerList == null) {
throw new SaTokenException("重置的侦听器集合不可以为空");
throw new SaTokenException("重置的侦听器集合不可以为空").setCode(SaErrorCode.CODE_10031);
}
SaTokenEventCenter.listenerList = listenerList;
}
@ -48,7 +49,7 @@ public class SaTokenEventCenter {
*/
public static void registerListener(SaTokenListener listener) {
if(listener == null) {
throw new SaTokenException("注册的侦听器不可以为空");
throw new SaTokenException("注册的侦听器不可以为空").setCode(SaErrorCode.CODE_10032);
}
listenerList.add(listener);
}
@ -59,11 +60,11 @@ public class SaTokenEventCenter {
*/
public static void registerListenerList(List<SaTokenListener> listenerList) {
if(listenerList == null) {
throw new SaTokenException("注册的侦听器不可以为空");
throw new SaTokenException("注册的侦听器集合不可以为空").setCode(SaErrorCode.CODE_10031);
}
for (SaTokenListener listener : listenerList) {
if(listener == null) {
throw new SaTokenException("注册的侦听器不可以为空");
throw new SaTokenException("注册的侦听器不可以为空").setCode(SaErrorCode.CODE_10032);
}
}
SaTokenEventCenter.listenerList.addAll(listenerList);

View File

@ -3,6 +3,7 @@ package cn.dev33.satoken.router;
import java.util.HashMap;
import java.util.Map;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
/**
@ -37,11 +38,11 @@ public enum SaHttpMethod {
*/
public static SaHttpMethod toEnum(String method) {
if(method == null) {
throw new SaTokenException("无效Method" + method);
throw new SaTokenException("无效Method" + method).setCode(SaErrorCode.CODE_10321);
}
SaHttpMethod reqMethod = map.get(method.toUpperCase());
if(reqMethod == null) {
throw new SaTokenException("无效Method" + method);
throw new SaTokenException("无效Method" + method).setCode(SaErrorCode.CODE_10321);
}
return reqMethod;
}

View File

@ -2,6 +2,7 @@ package cn.dev33.satoken.same;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SameTokenInvalidException;
import cn.dev33.satoken.util.SaFoxUtil;
@ -57,7 +58,7 @@ public class SaSameTemplate {
public void checkToken(String token) {
if(isValid(token) == false) {
token = (token == null ? "" : token);
throw new SameTokenInvalidException("无效Same-Token" + token);
throw new SameTokenInvalidException("无效Same-Token" + token).setCode(SaErrorCode.CODE_10301);
}
}

View File

@ -3,6 +3,9 @@ package cn.dev33.satoken.secure;
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
/**
* Sa-Token Base64工具类
* @author kong
@ -40,7 +43,7 @@ public class SaBase64Util {
try {
return encoder.encodeToString(text.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12101);
}
}
@ -53,7 +56,7 @@ public class SaBase64Util {
try {
return new String(decoder.decode(base64Text), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12101);
}
}

View File

@ -1,6 +1,5 @@
package cn.dev33.satoken.secure;
import java.security.InvalidParameterException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
@ -23,6 +22,7 @@ import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
/**
@ -70,7 +70,7 @@ public class SaSecureUtil {
}
return new String(strA);
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12111);
}
}
@ -98,7 +98,7 @@ public class SaSecureUtil {
}
return new String(chs);
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12112);
}
}
@ -127,7 +127,7 @@ public class SaSecureUtil {
return builder.toString();
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12113);
}
}
@ -164,7 +164,7 @@ public class SaSecureUtil {
byte[] result = cipher.doFinal(byteContent);
return encoder.encodeToString(result);
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12114);
}
}
@ -181,7 +181,7 @@ public class SaSecureUtil {
byte[] result = cipher.doFinal(decoder.decode(text));
return new String(result, "utf-8");
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12115);
}
}
@ -220,15 +220,9 @@ public class SaSecureUtil {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
KeyPair keyPair;
try {
keyPairGenerator.initialize(KEY_SIZE,
new SecureRandom(UUID.randomUUID().toString().replaceAll("-", "").getBytes()));
keyPair = keyPairGenerator.generateKeyPair();
} catch (InvalidParameterException e) {
throw e;
} catch (NullPointerException e) {
throw e;
}
keyPairGenerator.initialize(KEY_SIZE,
new SecureRandom(UUID.randomUUID().toString().replaceAll("-", "").getBytes()));
keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
@ -261,7 +255,7 @@ public class SaSecureUtil {
}
return stringBuffer.toString();
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12116);
}
}
@ -286,7 +280,7 @@ public class SaSecureUtil {
}
return stringBuffer.toString();
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12117);
}
}
@ -313,7 +307,7 @@ public class SaSecureUtil {
}
return stringBuffer.toString();
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12118);
}
}
@ -339,7 +333,7 @@ public class SaSecureUtil {
}
return stringBuffer.toString();
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12119);
}
}

View File

@ -20,6 +20,7 @@ import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.context.model.SaStorage;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.ApiDisabledException;
import cn.dev33.satoken.exception.DisableServiceException;
import cn.dev33.satoken.exception.NotLoginException;
@ -255,7 +256,7 @@ public class StpLogic {
public String getTokenValueNotNull(){
String tokenValue = getTokenValue();
if(SaFoxUtil.isEmpty(tokenValue)) {
throw new SaTokenException("未能读取到有效Token");
throw new SaTokenException("未能读取到有效Token").setCode(SaErrorCode.CODE_11001);
}
return tokenValue;
}
@ -351,7 +352,7 @@ public class StpLogic {
public String createLoginSession(Object id, SaLoginModel loginModel) {
// ------ 前置检查
SaTokenException.throwByNull(id, "账号id不能为空");
SaTokenException.throwByNull(id, "账号id不能为空", SaErrorCode.CODE_11002);
// ------ 1初始化 loginModel
SaTokenConfig config = getConfig();
@ -677,24 +678,24 @@ public class StpLogic {
// 如果获取不到token则抛出: 无token
String tokenValue = getTokenValue();
if(tokenValue == null) {
throw NotLoginException.newInstance(loginType, NotLoginException.NOT_TOKEN);
throw NotLoginException.newInstance(loginType, NotLoginException.NOT_TOKEN).setCode(SaErrorCode.CODE_11011);
}
// 查找此token对应loginId, 如果找不到则抛出无效token
String loginId = getLoginIdNotHandle(tokenValue);
if(loginId == null) {
throw NotLoginException.newInstance(loginType, NotLoginException.INVALID_TOKEN, tokenValue);
throw NotLoginException.newInstance(loginType, NotLoginException.INVALID_TOKEN, tokenValue).setCode(SaErrorCode.CODE_11012);
}
// 如果是已经过期则抛出已经过期
if(loginId.equals(NotLoginException.TOKEN_TIMEOUT)) {
throw NotLoginException.newInstance(loginType, NotLoginException.TOKEN_TIMEOUT, tokenValue);
throw NotLoginException.newInstance(loginType, NotLoginException.TOKEN_TIMEOUT, tokenValue).setCode(SaErrorCode.CODE_11013);
}
// 如果是已经被顶替下去了, 则抛出已被顶下线
if(loginId.equals(NotLoginException.BE_REPLACED)) {
throw NotLoginException.newInstance(loginType, NotLoginException.BE_REPLACED, tokenValue);
throw NotLoginException.newInstance(loginType, NotLoginException.BE_REPLACED, tokenValue).setCode(SaErrorCode.CODE_11014);
}
// 如果是已经被踢下线了, 则抛出已被踢下线
if(loginId.equals(NotLoginException.KICK_OUT)) {
throw NotLoginException.newInstance(loginType, NotLoginException.KICK_OUT, tokenValue);
throw NotLoginException.newInstance(loginType, NotLoginException.KICK_OUT, tokenValue).setCode(SaErrorCode.CODE_11015);
}
// 检查是否已经 [临时过期]
checkActivityTimeout(tokenValue);
@ -817,7 +818,7 @@ public class StpLogic {
* @return 对应的扩展数据
*/
public Object getExtra(String key) {
throw new ApiDisabledException();
throw new ApiDisabledException().setCode(SaErrorCode.CODE_11031);
}
/**
@ -827,7 +828,7 @@ public class StpLogic {
* @return 对应的扩展数据
*/
public Object getExtra(String tokenValue, String key) {
throw new ApiDisabledException();
throw new ApiDisabledException().setCode(SaErrorCode.CODE_11031);
}
@ -853,7 +854,7 @@ public class StpLogic {
* @param loginId 新的账号Id值
*/
public void updateTokenToIdMapping(String tokenValue, Object loginId) {
SaTokenException.throwBy(SaFoxUtil.isEmpty(loginId), "LoginId 不能为空");
SaTokenException.throwBy(SaFoxUtil.isEmpty(loginId), "LoginId 不能为空", SaErrorCode.CODE_11003);
getSaTokenDao().update(splicingKeyTokenValue(tokenValue), loginId.toString());
}
/**
@ -1096,7 +1097,7 @@ public class StpLogic {
}
// -2 代表已过期抛出异常
if(timeout == SaTokenDao.NOT_VALUE_EXPIRE) {
throw NotLoginException.newInstance(loginType, NotLoginException.TOKEN_TIMEOUT, tokenValue);
throw NotLoginException.newInstance(loginType, NotLoginException.TOKEN_TIMEOUT, tokenValue).setCode(SaErrorCode.CODE_11016);
}
// --- 至此验证已通过
@ -1353,7 +1354,7 @@ public class StpLogic {
*/
public void checkRole(String role) {
if(hasRole(role) == false) {
throw new NotRoleException(role, this.loginType);
throw new NotRoleException(role, this.loginType).setCode(SaErrorCode.CODE_11041);
}
}
@ -1366,7 +1367,7 @@ public class StpLogic {
List<String> roleList = getRoleList(loginId);
for (String role : roleArray) {
if(!hasElement(roleList, role)) {
throw new NotRoleException(role, this.loginType);
throw new NotRoleException(role, this.loginType).setCode(SaErrorCode.CODE_11041);
}
}
}
@ -1385,7 +1386,7 @@ public class StpLogic {
}
}
if(roleArray.length > 0) {
throw new NotRoleException(roleArray[0], this.loginType);
throw new NotRoleException(roleArray[0], this.loginType).setCode(SaErrorCode.CODE_11041);
}
}
@ -1466,7 +1467,7 @@ public class StpLogic {
*/
public void checkPermission(String permission) {
if(hasPermission(permission) == false) {
throw new NotPermissionException(permission, this.loginType);
throw new NotPermissionException(permission, this.loginType).setCode(SaErrorCode.CODE_11051);
}
}
@ -1479,7 +1480,7 @@ public class StpLogic {
List<String> permissionList = getPermissionList(loginId);
for (String permission : permissionArray) {
if(!hasElement(permissionList, permission)) {
throw new NotPermissionException(permission, this.loginType);
throw new NotPermissionException(permission, this.loginType).setCode(SaErrorCode.CODE_11051);
}
}
}
@ -1498,7 +1499,7 @@ public class StpLogic {
}
}
if(permissionArray.length > 0) {
throw new NotPermissionException(permissionArray[0], this.loginType);
throw new NotPermissionException(permissionArray[0], this.loginType).setCode(SaErrorCode.CODE_11051);
}
}
@ -1808,10 +1809,10 @@ public class StpLogic {
public void untieDisable(Object loginId, String... services) {
// 空值检查
if(SaFoxUtil.isEmpty(loginId)) {
throw new SaTokenException("请提供要解禁的账号");
throw new SaTokenException("请提供要解禁的账号").setCode(SaErrorCode.CODE_11062);
}
if(services == null || services.length == 0) {
throw new SaTokenException("请提供要解禁的服务");
throw new SaTokenException("请提供要解禁的服务").setCode(SaErrorCode.CODE_11063);
}
for (String service : services) {
@ -1846,13 +1847,13 @@ public class StpLogic {
public void disableLevel(Object loginId, String service, int level, long time) {
// 空值检查
if(SaFoxUtil.isEmpty(loginId)) {
throw new SaTokenException("请提供要封禁的账号");
throw new SaTokenException("请提供要封禁的账号").setCode(SaErrorCode.CODE_11062);
}
if(SaFoxUtil.isEmpty(service)) {
throw new SaTokenException("请提供要封禁的服务");
throw new SaTokenException("请提供要封禁的服务").setCode(SaErrorCode.CODE_11063);
}
if(level < SaTokenConsts.MIN_DISABLE_LEVEL) {
throw new SaTokenException("封禁等级不可以小于最小值:" + SaTokenConsts.MIN_DISABLE_LEVEL);
throw new SaTokenException("封禁等级不可以小于最小值:" + SaTokenConsts.MIN_DISABLE_LEVEL).setCode(SaErrorCode.CODE_11064);
}
// 标注为已被封禁
@ -1917,7 +1918,7 @@ public class StpLogic {
// s2. 检测被封禁的等级是否达到指定级别
Integer disableLevel = SaFoxUtil.getValueByType(value, int.class);
if(disableLevel >= level) {
throw new DisableServiceException(loginType, loginId, service, disableLevel, level, getDisableTime(loginId, service));
throw new DisableServiceException(loginType, loginId, service, disableLevel, level, getDisableTime(loginId, service)).setCode(SaErrorCode.CODE_11061);
}
}
@ -2069,7 +2070,7 @@ public class StpLogic {
public void checkSafe(String service) {
String tokenValue = getTokenValue();
if (isSafe(tokenValue, service) == false) {
throw new NotSafeException(loginType, tokenValue, service);
throw new NotSafeException(loginType, tokenValue, service).setCode(SaErrorCode.CODE_11071);
}
}

View File

@ -15,6 +15,7 @@ import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Pattern;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
/**
@ -451,7 +452,7 @@ public class SaFoxUtil {
try {
return URLEncoder.encode(url, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12103);
}
}
@ -464,7 +465,7 @@ public class SaFoxUtil {
try {
return URLDecoder.decode(url, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaErrorCode.CODE_12104);
}
}

View File

@ -1,8 +1,9 @@
package com.pj.test;
import cn.dev33.satoken.exception.*;
import com.pj.util.AjaxJson;
import cn.dev33.satoken.exception.*;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.event.EventListener;
import org.noear.solon.core.handle.Context;

View File

@ -53,39 +53,176 @@ SaToken 中的所有异常都是继承于 `SaTokenException` 的,也就是说
### 异常细分状态码-参照表
!> 目前仅对 sso 插件和 jwt 插件做了异常状态码细分,后续版本升级会支持更多模块
!> 部分插件因异常抛出点较少,暂未做状态码细分处理
**sa-token-code 核心包:**
#### sa-token-code 核心包
| code码值 | 含义 |
| :-------- | :-------- |
| -1 | 代表这个异常在抛出时未指定异常细分状态码 |
| 10001 | 未能获取有效的上下文处理器 |
| 10002 | 未能获取有效的上下文 |
| 10003 | JSON 转换器未实现 |
| 10011 | 未能从全局 StpLogic 集合中找到对应 type 的 StpLogic |
| 10021 | 指定的配置文件加载失败 |
| 10022 | 配置文件属性无法正常读取 |
| 10031 | 重置的侦听器集合不可以为空 |
| 10032 | 注册的侦听器不可以为空 |
| 10301 | 提供的 Same-Token 是无效的 |
| 10311 | 表示未能通过 Http Basic 认证校验 |
| 10321 | 提供的 HttpMethod 是无效的 |
| 11001 | 未能读取到有效Token |
| 11002 | 登录时的账号id值为空 |
| 11003 | 更改 Token 指向的 账号Id 时账号Id值为空 |
| 11011 | 未能读取到有效Token |
| 11012 | Token无效 |
| 11013 | Token已过期 |
| 11014 | Token已被顶下线 |
| 11015 | Token已被踢下线 |
| 11016 | Token已临时过期 |
| 11031 | 在未集成 sa-token-jwt 插件时调用 getExtra() 抛出异常 |
| 11041 | 缺少指定的角色 |
| 11051 | 缺少指定的权限 |
| 11061 | 当前账号未通过服务封禁校验 |
| 11062 | 提供要解禁的账号无效 |
| 11063 | 提供要解禁的服务无效 |
| 11064 | 提供要解禁的等级无效 |
| 11071 | 二级认证校验未通过 |
| 12001 | 请求中缺少指定的参数 |
| 12002 | 构建 Cookie 时缺少 name 参数 |
| 12003 | 构建 Cookie 时缺少 value 参数 |
| 12101 | Base64 编码异常 |
| 12102 | Base64 解码异常 |
| 12103 | URL 编码异常 |
| 12104 | URL 解码异常 |
| 12111 | md5 加密异常 |
| 12112 | sha1 加密异常 |
| 12113 | sha256 加密异常 |
| 12114 | AES 加密异常 |
| 12115 | AES 解密异常 |
| 12116 | RSA 公钥加密异常 |
| 12117 | RSA 私钥加密异常 |
| 12118 | RSA 公钥解密异常 |
| 12119 | RSA 私钥解密异常 |
**sa-token-sso 单点登录相关:**
#### sa-token-servlet
| code码值 | 含义 |
| :-------- | :-------- |
| 20001 | `redirect` 重定向 url 是一个无效地址 |
| 20002 | `redirect` 重定向 url 不在 allowUrl 允许的范围内 |
| 20003 | 接口调用方提供的 `secretkey` 秘钥无效 |
| 20004 | 提供的 `ticket` 是无效的 |
| 20005 | 在模式三下sso-client 调用 sso-server 端 校验ticket接口 时,得到的响应是校验失败 |
| 20006 | 在模式三下sso-client 调用 sso-server 端 单点注销接口 时,得到的响应是注销失败 |
| 20007 | http 请求调用 提供的 `timestamp` 与当前时间的差距超出允许的范围 |
| 20008 | http 请求调用 提供的 `sign` 无效 |
| 20009 | 本地系统没有配置 `secretkey` 字段 |
| 20001 | 转发失败 |
| 20002 | 重定向失败 |
**sa-token-jwt 插件相关:**
#### sa-token-spring-boot-starter
| code码值 | 含义 |
| :-------- | :-------- |
| 40101 | 对 jwt 字符串解析失败 |
| 40102 | 此 jwt 的签名无效 |
| 40103 | 此 jwt 的 `loginType` 字段不符合预期 |
| 40104 | 此 jwt 已超时 |
| 20101 | 企图在非 Web 上下文获取 Request、Response 等对象 |
| 20103 | 对象转 JSON 字符串失败 |
| 20104 | JSON 字符串转 Map 失败 |
| 20105 | 默认的 Filter 异常处理函数 |
#### sa-token-reactor-spring-boot-starter
| code码值 | 含义 |
| :-------- | :-------- |
| 20203 | 对象转 JSON 字符串失败 |
| 20204 | JSON 字符串转 Map 失败 |
| 20205 | 默认的 Filter 异常处理函数 |
#### sa-token-solon-plugin
| code码值 | 含义 |
| :-------- | :-------- |
| 20301 | 默认的拦截器异常处理函数 |
| 20302 | 默认的 Filter 异常处理函数 |
#### sa-token-sso 单点登录相关:
| code码值 | 含义 |
| :-------- | :-------- |
| 30001 | `redirect` 重定向 url 是一个无效地址 |
| 30002 | `redirect` 重定向 url 不在 allowUrl 允许的范围内 |
| 30003 | 接口调用方提供的 `secretkey` 秘钥无效 |
| 30004 | 提供的 `ticket` 是无效的 |
| 30005 | 在模式三下sso-client 调用 sso-server 端 校验ticket接口 时,得到的响应是校验失败 |
| 30006 | 在模式三下sso-client 调用 sso-server 端 单点注销接口 时,得到的响应是注销失败 |
| 30007 | http 请求调用 提供的 `timestamp` 与当前时间的差距超出允许的范围 |
| 30008 | http 请求调用 提供的 `sign` 无效 |
| 30009 | 本地系统没有配置 `secretkey` 字段 |
| 30010 | 本地系统没有配置 http 请求处理器 |
#### sa-token-oauth2 相关:
| code码值 | 含义 |
| :-------- | :-------- |
| 30101 | client_id 不可为空 |
| 30102 | scope 不可为空 |
| 30103 | redirect_uri 不可为空 |
| 30104 | LoginId 不可为空 |
| 30105 | 无效client_id |
| 30106 | 无效access_token |
| 30107 | 无效 client_token |
| 30108 | Access-Token 不具备指定的 Scope |
| 30109 | Client-Token 不具备指定的 Scope |
| 30110 | 无效 code 码 |
| 30111 | 无效 Refresh-Token |
| 30112 | 请求的Scope暂未签约 |
| 30113 | 无效redirect_url |
| 30114 | 非法redirect_url |
| 30115 | 无效client_secret |
| 30116 | 请求的Scope暂未签约 |
| 30117 | 无效code |
| 30118 | 无效client_id |
| 30119 | 无效client_secret |
| 30120 | 无效redirect_uri |
| 30121 | 无效refresh_token |
| 30122 | 无效client_id |
| 30123 | 无效client_secret |
| 30124 | 无效client_id |
| 30125 | 无效response_type |
| 30131 | 暂未开放授权码模式 |
| 30132 | 暂未开放隐藏式模式 |
| 30133 | 暂未开放密码式模式 |
| 30134 | 暂未开放凭证式模式 |
#### sa-token-jwt 插件相关:
| code码值 | 含义 |
| :-------- | :-------- |
| 30201 | 对 jwt 字符串解析失败 |
| 30202 | 此 jwt 的签名无效 |
| 30203 | 此 jwt 的 `loginType` 字段不符合预期 |
| 30204 | 此 jwt 已超时 |
| 30205 | 没有配置jwt秘钥 |
| 30206 | 登录时提供的账号id为空 |
#### sa-token-temp-jwt 插件相关:
| code码值 | 含义 |
| :-------- | :-------- |
| 30301 | jwt 模式没有提供秘钥 |
| 30302 | jwt 模式不可以删除 Token |
| 30303 | Token已超时 |

View File

@ -4,8 +4,8 @@ import java.util.Map;
import java.util.Objects;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.jwt.error.SaJwtErrorCode;
import cn.dev33.satoken.jwt.exception.SaJwtException;
import cn.dev33.satoken.jwt.exception.SaJwtExceptionCode;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWT;
@ -146,19 +146,19 @@ public class SaJwtTemplate {
try {
jwt = JWT.of(token);
} catch (JWTException e) {
throw new SaJwtException("jwt 解析失败:" + token, e).setCode(SaJwtExceptionCode.CODE_40101);
throw new SaJwtException("jwt 解析失败:" + token, e).setCode(SaJwtErrorCode.CODE_30201);
}
JSONObject payloads = jwt.getPayloads();
// 校验 Token 签名
boolean verify = jwt.setKey(keyt.getBytes()).verify();
if(verify == false) {
throw new SaJwtException("jwt 签名无效:" + token).setCode(SaJwtExceptionCode.CODE_40102);
throw new SaJwtException("jwt 签名无效:" + token).setCode(SaJwtErrorCode.CODE_30202);
};
// 校验 loginType
if(Objects.equals(loginType, payloads.getStr(LOGIN_TYPE)) == false) {
throw new SaJwtException("jwt loginType 无效:" + token).setCode(SaJwtExceptionCode.CODE_40103);
throw new SaJwtException("jwt loginType 无效:" + token).setCode(SaJwtErrorCode.CODE_30203);
}
// 校验 Token 有效期
@ -166,7 +166,7 @@ public class SaJwtTemplate {
Long effTime = payloads.getLong(EFF, 0L);
if(effTime != NEVER_EXPIRE) {
if(effTime == null || effTime < System.currentTimeMillis()) {
throw new SaJwtException("jwt 已过期:" + token).setCode(SaJwtExceptionCode.CODE_40104);
throw new SaJwtException("jwt 已过期:" + token).setCode(SaJwtErrorCode.CODE_30204);
}
}
}

View File

@ -6,7 +6,7 @@ import java.util.Map;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.exception.ApiDisabledException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.jwt.error.SaJwtErrorCode;
import cn.dev33.satoken.jwt.exception.SaJwtException;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpLogic;
@ -40,7 +40,7 @@ public class StpLogicJwtForMixin extends StpLogic {
*/
public String jwtSecretKey() {
String keyt = getConfig().getJwtSecretKey();
SaTokenException.throwByNull(keyt, "请配置jwt秘钥");
SaJwtException.throwByNull(keyt, "请配置jwt秘钥", SaJwtErrorCode.CODE_30205);
return keyt;
}

View File

@ -2,7 +2,8 @@ package cn.dev33.satoken.jwt;
import java.util.Map;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.jwt.error.SaJwtErrorCode;
import cn.dev33.satoken.jwt.exception.SaJwtException;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
@ -34,7 +35,7 @@ public class StpLogicJwtForSimple extends StpLogic {
*/
public String jwtSecretKey() {
String keyt = getConfig().getJwtSecretKey();
SaTokenException.throwByNull(keyt, "请配置jwt秘钥");
SaJwtException.throwByNull(keyt, "请配置jwt秘钥", SaJwtErrorCode.CODE_30205);
return keyt;
}

View File

@ -5,7 +5,7 @@ import java.util.Map;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.exception.ApiDisabledException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.jwt.error.SaJwtErrorCode;
import cn.dev33.satoken.jwt.exception.SaJwtException;
import cn.dev33.satoken.listener.SaTokenEventCenter;
import cn.dev33.satoken.stp.SaLoginModel;
@ -42,7 +42,7 @@ public class StpLogicJwtForStateless extends StpLogic {
*/
public String jwtSecretKey() {
String keyt = getConfig().getJwtSecretKey();
SaTokenException.throwByNull(keyt, "请配置jwt秘钥");
SaJwtException.throwByNull(keyt, "请配置jwt秘钥", SaJwtErrorCode.CODE_30205);
return keyt;
}
@ -90,7 +90,7 @@ public class StpLogicJwtForStateless extends StpLogic {
*/
@Override
public String createLoginSession(Object id, SaLoginModel loginModel) {
SaTokenException.throwByNull(id, "账号id不能为空");
SaJwtException.throwByNull(id, "账号id不能为空", SaJwtErrorCode.CODE_30206);
// ------ 1初始化 loginModel
loginModel.build(getConfig());

View File

@ -0,0 +1,29 @@
package cn.dev33.satoken.jwt.error;
/**
* 定义 sa-token-jwt 所有异常细分状态码
*
* @author kong
* @since 2022-10-31
*/
public class SaJwtErrorCode {
/** 对 jwt 字符串解析失败 */
public static final int CODE_30201 = 30201;
/** 此 jwt 的签名无效 */
public static final int CODE_30202 = 30202;
/** 此 jwt 的 loginType 字段不符合预期 */
public static final int CODE_30203 = 30203;
/** 此 jwt 已超时 */
public static final int CODE_30204 = 30204;
/** 没有配置jwt秘钥 */
public static final int CODE_30205 = 30205;
/** 登录时提供的账号id为空 */
public static final int CODE_30206 = 30206;
}

View File

@ -1,12 +1,14 @@
package cn.dev33.satoken.jwt.exception;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.util.SaFoxUtil;
/**
* 一个异常代表 jwt 解析错误
* 一个异常代表 jwt 相关错误
*
* @author kong
* @since 2022-10-31
*/
public class SaJwtException extends SaTokenException {
@ -52,5 +54,17 @@ public class SaJwtException extends SaTokenException {
throw new SaJwtException(message);
}
}
/**
* 如果value==null或者isEmpty则抛出message异常
* @param value
* @param message 异常信息
* @param code 异常细分状态码
*/
public static void throwByNull(Object value, String message, int code) {
if(SaFoxUtil.isEmpty(value)) {
throw new SaJwtException(message).setCode(code);
}
}
}

View File

@ -1,23 +0,0 @@
package cn.dev33.satoken.jwt.exception;
/**
* 定义所有 JWT 异常细分状态码
*
* @author kong
* @since: 2022-5-1
*/
public class SaJwtExceptionCode {
/** 对 jwt 字符串解析失败 */
public static final int CODE_40101 = 40101;
/** 此 jwt 的签名无效 */
public static final int CODE_40102 = 40102;
/** 此 jwt 的 loginType 字段不符合预期 */
public static final int CODE_40103 = 40103;
/** 此 jwt 已超时 */
public static final int CODE_40104 = 40104;
}

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;
}

View File

@ -6,7 +6,8 @@ import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.sso.error.SaSsoErrorCode;
import cn.dev33.satoken.sso.exception.SaSsoException;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult;
@ -385,7 +386,7 @@ public class SaSsoConfig implements Serializable {
* SSO-Client端发送Http请求的处理函数
*/
public Function<String, String> sendHttp = url -> {
throw new SaTokenException("请配置 Http 请求处理器");
throw new SaSsoException("请配置 Http 请求处理器").setCode(SaSsoErrorCode.CODE_30010);
};

View File

@ -4,8 +4,8 @@ import cn.dev33.satoken.config.SaSsoConfig;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.sso.error.SaSsoErrorCode;
import cn.dev33.satoken.sso.exception.SaSsoException;
import cn.dev33.satoken.sso.exception.SaSsoExceptionCode;
import cn.dev33.satoken.sso.name.ApiName;
import cn.dev33.satoken.sso.name.ParamName;
import cn.dev33.satoken.stp.StpLogic;
@ -257,7 +257,7 @@ public class SaSsoHandle {
// ------- 2如果 loginId 无值说明 ticket 无效
if(SaFoxUtil.isEmpty(loginId)) {
throw new SaSsoException("无效ticket" + ticket).setCode(SaSsoExceptionCode.CODE_20004);
throw new SaSsoException("无效ticket" + ticket).setCode(SaSsoErrorCode.CODE_30004);
} else {
// 3如果 loginId 有值说明 ticket 有效此时进行登录并重定向至back地址
stpLogic.login(loginId);
@ -311,7 +311,7 @@ public class SaSsoHandle {
return ssoLogoutBack(req, res);
} else {
// sso-server 回应的消息作为异常抛出
throw new SaSsoException(result.getMsg()).setCode(SaSsoExceptionCode.CODE_20006);
throw new SaSsoException(result.getMsg()).setCode(SaSsoErrorCode.CODE_30006);
}
}
@ -400,7 +400,7 @@ public class SaSsoHandle {
return result.getData();
} else {
// sso-server 回应的消息作为异常抛出
throw new SaSsoException(result.getMsg()).setCode(SaSsoExceptionCode.CODE_20005);
throw new SaSsoException(result.getMsg()).setCode(SaSsoErrorCode.CODE_30005);
}
} else {
// q2使用模式二直连Redis校验ticket

View File

@ -4,8 +4,8 @@ import cn.dev33.satoken.config.SaSsoConfig;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.sso.error.SaSsoErrorCode;
import cn.dev33.satoken.sso.exception.SaSsoException;
import cn.dev33.satoken.sso.exception.SaSsoExceptionCode;
import cn.dev33.satoken.sso.name.ApiName;
import cn.dev33.satoken.sso.name.ParamName;
import cn.dev33.satoken.stp.StpLogic;
@ -276,7 +276,7 @@ public class SaSsoProcessor {
// ------- 2如果 loginId 无值说明 ticket 无效
if(SaFoxUtil.isEmpty(loginId)) {
throw new SaSsoException("无效ticket" + ticket).setCode(SaSsoExceptionCode.CODE_20004);
throw new SaSsoException("无效ticket" + ticket).setCode(SaSsoErrorCode.CODE_30004);
} else {
// 3如果 loginId 有值说明 ticket 有效此时进行登录并重定向至back地址
stpLogic.login(loginId);
@ -352,7 +352,7 @@ public class SaSsoProcessor {
return ssoLogoutBack(req, res);
} else {
// sso-server 回应的消息作为异常抛出
throw new SaSsoException(result.getMsg()).setCode(SaSsoExceptionCode.CODE_20006);
throw new SaSsoException(result.getMsg()).setCode(SaSsoErrorCode.CODE_30006);
}
}
@ -446,7 +446,7 @@ public class SaSsoProcessor {
return result.getData();
} else {
// sso-server 回应的消息作为异常抛出
throw new SaSsoException(result.getMsg()).setCode(SaSsoExceptionCode.CODE_20005);
throw new SaSsoException(result.getMsg()).setCode(SaSsoErrorCode.CODE_30005);
}
} else {
// q2使用模式二直连Redis校验ticket

View File

@ -11,8 +11,8 @@ import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.config.SaSsoConfig;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.sso.error.SaSsoErrorCode;
import cn.dev33.satoken.sso.exception.SaSsoException;
import cn.dev33.satoken.sso.exception.SaSsoExceptionCode;
import cn.dev33.satoken.sso.name.ApiName;
import cn.dev33.satoken.sso.name.ParamName;
import cn.dev33.satoken.stp.StpLogic;
@ -211,7 +211,7 @@ public class SaSsoTemplate {
// 1是否是一个有效的url
if(SaFoxUtil.isUrl(url) == false) {
throw new SaSsoException("无效redirect" + url).setCode(SaSsoExceptionCode.CODE_20001);
throw new SaSsoException("无效redirect" + url).setCode(SaSsoErrorCode.CODE_30001);
}
// 2截取掉?后面的部分
@ -223,7 +223,7 @@ public class SaSsoTemplate {
// 3是否在[允许地址列表]之中
List<String> authUrlList = Arrays.asList(getAllowUrl().replaceAll(" ", "").split(","));
if(SaStrategy.me.hasElement.apply(authUrlList, url) == false) {
throw new SaSsoException("非法redirect" + url).setCode(SaSsoExceptionCode.CODE_20002);
throw new SaSsoException("非法redirect" + url).setCode(SaSsoErrorCode.CODE_30002);
}
// 校验通过
@ -448,7 +448,7 @@ public class SaSsoTemplate {
// 默认从配置文件中返回
String secretkey = SaSsoManager.getConfig().getSecretkey();
if(SaFoxUtil.isEmpty(secretkey)) {
throw new SaSsoException("请配置 secretkey 参数").setCode(SaSsoExceptionCode.CODE_20009);
throw new SaSsoException("请配置 secretkey 参数").setCode(SaSsoErrorCode.CODE_30009);
}
return secretkey;
}
@ -460,7 +460,7 @@ public class SaSsoTemplate {
@Deprecated
public void checkSecretkey(String secretkey) {
if(SaFoxUtil.isEmpty(secretkey) || secretkey.equals(getSecretkey()) == false) {
throw new SaSsoException("无效秘钥:" + secretkey).setCode(SaSsoExceptionCode.CODE_20003);
throw new SaSsoException("无效秘钥:" + secretkey).setCode(SaSsoErrorCode.CODE_30003);
}
}
@ -519,7 +519,7 @@ public class SaSsoTemplate {
// 校验签名
String calcSign = getSign(loginId, timestamp, nonce, getSecretkey());
if(calcSign.equals(sign) == false) {
throw new SaSsoException("签名无效:" + calcSign).setCode(SaSsoExceptionCode.CODE_20008);
throw new SaSsoException("签名无效:" + calcSign).setCode(SaSsoErrorCode.CODE_30008);
}
}
@ -531,7 +531,7 @@ public class SaSsoTemplate {
long disparity = Math.abs(System.currentTimeMillis() - timestamp);
long allowDisparity = SaSsoManager.getConfig().getTimestampDisparity();
if(allowDisparity != -1 && disparity > allowDisparity) {
throw new SaSsoException("timestamp 超出允许的范围").setCode(SaSsoExceptionCode.CODE_20007);
throw new SaSsoException("timestamp 超出允许的范围").setCode(SaSsoErrorCode.CODE_30007);
}
}

View File

@ -1,38 +1,41 @@
package cn.dev33.satoken.sso.exception;
package cn.dev33.satoken.sso.error;
/**
* 定义所有 SSO 异常细分状态码
* 定义 sa-token-sso 所有异常细分状态码
*
* @author kong
* @since: 2022-4-25
* @since: 2022-10-31
*/
public class SaSsoExceptionCode {
public interface SaSsoErrorCode {
/** redirect 重定向 url 是一个无效地址 */
public static final int CODE_20001 = 20001;
public static final int CODE_30001 = 30001;
/** redirect 重定向 url 不在 allowUrl 允许的范围内 */
public static final int CODE_20002 = 20002;
public static final int CODE_30002 = 30002;
/** 接口调用方提供的 secretkey 秘钥无效 */
public static final int CODE_20003 = 20003;
public static final int CODE_30003 = 30003;
/** 提供的 ticket 是无效的 */
public static final int CODE_20004 = 20004;
public static final int CODE_30004 = 30004;
/** 在模式三下sso-client 调用 sso-server 端 校验ticket接口 时,得到的响应是校验失败 */
public static final int CODE_20005 = 20005;
public static final int CODE_30005 = 30005;
/** 在模式三下sso-client 调用 sso-server 端 单点注销接口 时,得到的响应是注销失败 */
public static final int CODE_20006 = 20006;
public static final int CODE_30006 = 30006;
/** http 请求调用 提供的 timestamp 与当前时间的差距超出允许的范围 */
public static final int CODE_20007 = 20007;
public static final int CODE_30007 = 30007;
/** http 请求调用 提供的 sign 无效 */
public static final int CODE_20008 = 20008;
public static final int CODE_30008 = 30008;
/** 本地系统没有配置 secretkey 字段 */
public static final int CODE_20009 = 20009;
public static final int CODE_30009 = 30009;
/** 本地系统没有配置 http 请求处理器 */
public static final int CODE_30010 = 30010;
}

View File

@ -2,6 +2,7 @@ package cn.dev33.satoken.temp.jwt;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.temp.jwt.error.SaTempJwtErrorCode;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
@ -78,7 +79,7 @@ public class SaJwtUtil {
// 验证是否超时
Long eff = claims.get(KEY_EFF, Long.class);
if((eff == null || eff < System.currentTimeMillis()) && eff != NEVER_EXPIRE) {
throw new SaTokenException("Token已超时");
throw new SaTokenException("Token已超时").setCode(SaTempJwtErrorCode.CODE_30303);
}
// 获取数据

View File

@ -1,8 +1,10 @@
package cn.dev33.satoken.temp.jwt;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.exception.ApiDisabledException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.temp.SaTempInterface;
import cn.dev33.satoken.temp.jwt.error.SaTempJwtErrorCode;
import cn.dev33.satoken.util.SaFoxUtil;
/**
@ -44,7 +46,7 @@ public class SaTempForJwt implements SaTempInterface {
*/
@Override
public void deleteToken(String token) {
throw new SaTokenException("jwt cannot delete token");
throw new ApiDisabledException("jwt cannot delete token").setCode(SaTempJwtErrorCode.CODE_30302);
}
/**
@ -55,7 +57,7 @@ public class SaTempForJwt implements SaTempInterface {
public String getJwtSecretKey() {
String jwtSecretKey = SaManager.getConfig().getJwtSecretKey();
if(SaFoxUtil.isEmpty(jwtSecretKey)) {
throw new SaTokenException("请配置jwtSecretKey");
throw new SaTokenException("请配置jwtSecretKey").setCode(SaTempJwtErrorCode.CODE_30301);
}
return jwtSecretKey;
}

View File

@ -0,0 +1,20 @@
package cn.dev33.satoken.temp.jwt.error;
/**
* 定义 sa-token-temp-jwt 所有异常细分状态码
*
* @author kong
* @since 2022-10-31
*/
public class SaTempJwtErrorCode {
/** jwt 模式没有提供秘钥 */
public static final int CODE_30301 = 30301;
/** jwt 模式不可以删除 Token */
public static final int CODE_30302 = 30302;
/** Token已超时 */
public static final int CODE_30303 = 30303;
}

View File

@ -0,0 +1,20 @@
package cn.dev33.satoken.reactor.error;
/**
* 定义 sa-token-reactor-spring-boot-starter 所有异常细分状态码
*
* @author kong
* @since: 2022-10-30
*/
public interface SaReactorSpringBootErrorCode {
/** 对象转 JSON 字符串失败 */
public static final int CODE_20203 = 20203;
/** JSON 字符串转 Map 失败 */
public static final int CODE_20204 = 20204;
/** 默认的 Filter 异常处理函数 */
public static final int CODE_20205 = 20205;
}

View File

@ -16,6 +16,7 @@ import cn.dev33.satoken.filter.SaFilterAuthStrategy;
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
import cn.dev33.satoken.reactor.context.SaReactorHolder;
import cn.dev33.satoken.reactor.context.SaReactorSyncHolder;
import cn.dev33.satoken.reactor.error.SaReactorSpringBootErrorCode;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.util.SaTokenConsts;
import reactor.core.publisher.Mono;
@ -108,7 +109,7 @@ public class SaReactorFilter implements WebFilter {
* 异常处理函数每次[认证函数]发生异常时执行此函数
*/
public SaFilterErrorStrategy error = e -> {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaReactorSpringBootErrorCode.CODE_20205);
};
/**

View File

@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import cn.dev33.satoken.exception.SaJsonConvertException;
import cn.dev33.satoken.json.SaJsonTemplate;
import cn.dev33.satoken.reactor.error.SaReactorSpringBootErrorCode;
/**
* JSON 转换器 Jackson 版实现
@ -31,7 +32,7 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new SaJsonConvertException(e);
throw new SaJsonConvertException(e).setCode(SaReactorSpringBootErrorCode.CODE_20203);
}
}
@ -45,7 +46,7 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate {
Map<String, Object> map = objectMapper.readValue(jsonStr, Map.class);
return map;
} catch (JsonProcessingException e) {
throw new SaJsonConvertException(e);
throw new SaJsonConvertException(e).setCode(SaReactorSpringBootErrorCode.CODE_20204);
}
}

View File

@ -0,0 +1,17 @@
package cn.dev33.satoken.servlet.error;
/**
* 定义 sa-token-servlet 所有异常细分状态码
*
* @author kong
* @since: 2022-10-30
*/
public interface SaServletErrorCode {
/** 转发失败 */
public static final int CODE_20001 = 20001;
/** 重定向失败 */
public static final int CODE_20002 = 20002;
}

View File

@ -10,6 +10,7 @@ import javax.servlet.http.HttpServletResponse;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.servlet.error.SaServletErrorCode;
import cn.dev33.satoken.util.SaFoxUtil;
/**
@ -110,7 +111,7 @@ public class SaRequestForServlet implements SaRequest {
request.getRequestDispatcher(path).forward(request, response);
return null;
} catch (ServletException | IOException e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaServletErrorCode.CODE_20001);
}
}

View File

@ -4,6 +4,7 @@ import javax.servlet.http.HttpServletResponse;
import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.servlet.error.SaServletErrorCode;
/**
* Response for Servlet
@ -70,7 +71,7 @@ public class SaResponseForServlet implements SaResponse {
try {
response.sendRedirect(url);
} catch (Exception e) {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaServletErrorCode.CODE_20002);
}
return null;
}

View File

@ -0,0 +1,17 @@
package cn.dev33.satoken.solon.error;
/**
* 定义 sa-token-solon-plugin 所有异常细分状态码
*
* @author kong
* @since: 2022-10-30
*/
public interface SaSolonErrorCode {
/** 默认的拦截器异常处理函数 */
public static final int CODE_20301 = 20301;
/** 默认的 Filter 异常处理函数 */
public static final int CODE_20302 = 20302;
}

View File

@ -19,6 +19,7 @@ import cn.dev33.satoken.exception.StopMatchException;
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.solon.error.SaSolonErrorCode;
import cn.dev33.satoken.strategy.SaStrategy;
/**
@ -123,7 +124,7 @@ public class SaTokenPathFilter implements Filter {
if (e instanceof SaTokenException) {
throw (SaTokenException) e;
} else {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaSolonErrorCode.CODE_20302);
}
};

View File

@ -7,6 +7,7 @@ import cn.dev33.satoken.exception.StopMatchException;
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.solon.error.SaSolonErrorCode;
import cn.dev33.satoken.strategy.SaStrategy;
import org.noear.solon.core.handle.Action;
import org.noear.solon.core.handle.Context;
@ -119,7 +120,7 @@ public class SaTokenPathInterceptor implements Handler {
if (e instanceof SaTokenException) {
throw (SaTokenException) e;
} else {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaSolonErrorCode.CODE_20301);
}
};

View File

@ -0,0 +1,23 @@
package cn.dev33.satoken.error;
/**
* 定义 sa-token-spring-boot-starter 所有异常细分状态码
*
* @author kong
* @since: 2022-10-30
*/
public interface SaSpringBootErrorCode {
/** 企图在非 Web 上下文获取 Request、Response 等对象 */
public static final int CODE_20101 = 20101;
/** 对象转 JSON 字符串失败 */
public static final int CODE_20103 = 20103;
/** JSON 字符串转 Map 失败 */
public static final int CODE_20104 = 20104;
/** 默认的 Filter 异常处理函数 */
public static final int CODE_20105 = 20105;
}

View File

@ -14,6 +14,7 @@ import javax.servlet.ServletResponse;
import org.springframework.core.annotation.Order;
import cn.dev33.satoken.error.SaSpringBootErrorCode;
import cn.dev33.satoken.exception.BackResultException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.exception.StopMatchException;
@ -108,7 +109,7 @@ public class SaServletFilter implements Filter {
* 异常处理函数每次[认证函数]发生异常时执行此函数
*/
public SaFilterErrorStrategy error = e -> {
throw new SaTokenException(e);
throw new SaTokenException(e).setCode(SaSpringBootErrorCode.CODE_20105);
};
/**

View File

@ -6,7 +6,8 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.error.SaSpringBootErrorCode;
import cn.dev33.satoken.exception.NotWebContextException;
/**
* SpringMVC相关操作
@ -25,7 +26,7 @@ public class SpringMVCUtil {
public static HttpServletRequest getRequest() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes == null) {
throw new SaTokenException("非Web上下文无法获取Request");
throw new NotWebContextException("非Web上下文无法获取Request").setCode(SaSpringBootErrorCode.CODE_20101);
}
return servletRequestAttributes.getRequest();
}
@ -37,7 +38,7 @@ public class SpringMVCUtil {
public static HttpServletResponse getResponse() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes == null) {
throw new SaTokenException("非Web上下文无法获取Response");
throw new NotWebContextException("非Web上下文无法获取Response").setCode(SaSpringBootErrorCode.CODE_20101);
}
return servletRequestAttributes.getResponse();
}

View File

@ -5,6 +5,7 @@ import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.dev33.satoken.error.SaSpringBootErrorCode;
import cn.dev33.satoken.exception.SaJsonConvertException;
import cn.dev33.satoken.json.SaJsonTemplate;
@ -31,7 +32,7 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new SaJsonConvertException(e);
throw new SaJsonConvertException(e).setCode(SaSpringBootErrorCode.CODE_20103);
}
}
@ -45,7 +46,7 @@ public class SaJsonTemplateForJackson implements SaJsonTemplate {
Map<String, Object> map = objectMapper.readValue(jsonStr, Map.class);
return map;
} catch (JsonProcessingException e) {
throw new SaJsonConvertException(e);
throw new SaJsonConvertException(e).setCode(SaSpringBootErrorCode.CODE_20104);
}
}