mirror of
https://gitee.com/dromara/sa-token.git
synced 2026-02-27 16:50:24 +08:00
sa-token-solon-plugin 适配自定义注解扩展
This commit is contained in:
@@ -19,6 +19,7 @@ import cn.dev33.satoken.annotation.*;
|
||||
import cn.dev33.satoken.annotation.handler.*;
|
||||
import cn.dev33.satoken.fun.strategy.SaCheckMethodAnnotationFunction;
|
||||
import cn.dev33.satoken.fun.strategy.SaGetAnnotationFunction;
|
||||
import cn.dev33.satoken.fun.strategy.SaIsAnnotationPresentFunction;
|
||||
import cn.dev33.satoken.listener.SaTokenEventCenter;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
@@ -121,4 +122,12 @@ public final class SaAnnotationStrategy {
|
||||
return element.getAnnotation(annotationClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* 判断一个 Method 或其所属 Class 是否包含指定注解
|
||||
*/
|
||||
public SaIsAnnotationPresentFunction isAnnotationPresent = (method, annotationClass) -> {
|
||||
return instance.getAnnotation.apply(method, annotationClass) != null ||
|
||||
instance.getAnnotation.apply(method.getDeclaringClass(), annotationClass) != null;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.pj.satoken.custom_annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 账号校验:在标注一个方法上时,要求前端必须提交相应的账号密码参数才能访问方法。
|
||||
*
|
||||
* @author click33
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE})
|
||||
public @interface CheckAccount {
|
||||
|
||||
/**
|
||||
* 需要校验的账号
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* 需要校验的密码
|
||||
*
|
||||
* @return /
|
||||
*/
|
||||
String pwd();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.pj.satoken.custom_annotation.handler;
|
||||
|
||||
import cn.dev33.satoken.annotation.handler.SaAnnotationAbstractHandler;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import com.pj.satoken.custom_annotation.CheckAccount;
|
||||
import org.noear.solon.annotation.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 注解 CheckAccount 的处理器
|
||||
*
|
||||
* @author click33
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class CheckAccountHandler implements SaAnnotationAbstractHandler<CheckAccount> {
|
||||
|
||||
// 指定这个处理器要处理哪个注解
|
||||
@Override
|
||||
public Class<CheckAccount> getHandlerAnnotationClass() {
|
||||
return CheckAccount.class;
|
||||
}
|
||||
|
||||
// 每次请求校验注解时,会执行的方法
|
||||
@Override
|
||||
public void checkMethod(CheckAccount at, Method method) {
|
||||
// 获取前端请求提交的参数
|
||||
String name = SaHolder.getRequest().getParamNotNull("name");
|
||||
String pwd = SaHolder.getRequest().getParamNotNull("pwd");
|
||||
|
||||
// 与注解中指定的值相比较
|
||||
if(name.equals(at.name()) && pwd.equals(at.pwd()) ) {
|
||||
// 校验通过,什么也不做
|
||||
} else {
|
||||
// 校验不通过,则抛出异常
|
||||
throw new SaTokenException("账号或密码错误,未通过校验");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package cn.dev33.satoken.oauth2.logic;
|
||||
|
||||
import cn.dev33.satoken.basic.SaBasicUtil;
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.context.model.SaResponse;
|
||||
import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil;
|
||||
import cn.dev33.satoken.oauth2.SaOAuth2Manager;
|
||||
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
|
||||
import cn.dev33.satoken.oauth2.error.SaOAuth2ErrorCode;
|
||||
@@ -27,11 +27,7 @@ import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.Api;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.GrantType;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.Param;
|
||||
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts.ResponseType;
|
||||
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.oauth2.model.*;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
@@ -179,7 +175,7 @@ public class SaOAuth2Handle {
|
||||
*/
|
||||
public static Object token(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
|
||||
// 获取参数
|
||||
String authorizationValue = SaBasicUtil.getAuthorizationValue();
|
||||
String authorizationValue = SaHttpBasicUtil.getAuthorizationValue();
|
||||
String clientId;
|
||||
String clientSecret;
|
||||
// gitlab回调token接口时,按照的是标准的oauth2协议的basic请求头,basic中会包含client_id和client_secret的信息
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
package cn.dev33.satoken.solon;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.httpauth.basic.SaHttpBasicTemplate;
|
||||
import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil;
|
||||
import cn.dev33.satoken.annotation.handler.SaAnnotationAbstractHandler;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.context.second.SaTokenSecondContextCreator;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.httpauth.basic.SaHttpBasicTemplate;
|
||||
import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil;
|
||||
import cn.dev33.satoken.httpauth.digest.SaHttpDigestTemplate;
|
||||
import cn.dev33.satoken.httpauth.digest.SaHttpDigestUtil;
|
||||
import cn.dev33.satoken.json.SaJsonTemplate;
|
||||
@@ -36,6 +37,7 @@ import cn.dev33.satoken.solon.sso.SaSsoAutoConfigure;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.strategy.SaAnnotationStrategy;
|
||||
import cn.dev33.satoken.temp.SaTempInterface;
|
||||
import org.noear.solon.Solon;
|
||||
import org.noear.solon.core.AppContext;
|
||||
@@ -95,6 +97,11 @@ public class XPluginImp implements Plugin {
|
||||
SaTokenEventCenter.registerListener(sl);
|
||||
});
|
||||
|
||||
// 注入自定义注解处理器 Bean (可以有多个)
|
||||
context.subBeansOfType(SaAnnotationAbstractHandler.class, sl -> {
|
||||
SaAnnotationStrategy.instance.registerAnnotationHandler(sl);
|
||||
});
|
||||
|
||||
// 注入权限认证 Bean
|
||||
context.getBeanAsync(StpInterface.class, bean -> {
|
||||
SaManager.setStpInterface(bean);
|
||||
|
||||
@@ -23,6 +23,7 @@ import cn.dev33.satoken.filter.SaFilterAuthStrategy;
|
||||
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
|
||||
import cn.dev33.satoken.filter.SaFilter;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.strategy.SaAnnotationStrategy;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import org.noear.solon.Solon;
|
||||
import org.noear.solon.core.handle.*;
|
||||
@@ -202,16 +203,13 @@ public class SaTokenFilter implements SaFilter, Filter { //之所以改名,为
|
||||
private boolean authAnno(Action action) {
|
||||
//2.验证注解处理
|
||||
if (isAnnotation && action != null) {
|
||||
// 获取此请求对应的 Method 处理函数
|
||||
Method method = action.method().getMethod();
|
||||
|
||||
// 如果此 Method 或其所属 Class 标注了 @SaIgnore,则忽略掉鉴权
|
||||
if (SaStrategy.instance.isAnnotationPresent.apply(method, SaIgnore.class)) {
|
||||
// 注解校验
|
||||
try{
|
||||
Method method = action.method().getMethod();
|
||||
SaAnnotationStrategy.instance.checkMethodAnnotation.accept(method);
|
||||
} catch (StopMatchException ignored) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 注解校验
|
||||
SaStrategy.instance.checkMethodAnnotation.accept(method);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package cn.dev33.satoken.solon.integration;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.dev33.satoken.exception.BackResultException;
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.exception.StopMatchException;
|
||||
@@ -23,7 +22,7 @@ import cn.dev33.satoken.filter.SaFilter;
|
||||
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
|
||||
import cn.dev33.satoken.filter.SaFilterErrorStrategy;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import cn.dev33.satoken.strategy.SaAnnotationStrategy;
|
||||
import org.noear.solon.core.handle.*;
|
||||
import org.noear.solon.core.route.RouterInterceptor;
|
||||
import org.noear.solon.core.route.RouterInterceptorChain;
|
||||
@@ -237,16 +236,13 @@ public class SaTokenInterceptor implements SaFilter, RouterInterceptor {
|
||||
private boolean authAnno(Action action) {
|
||||
//2.验证注解处理
|
||||
if (isAnnotation && action != null) {
|
||||
// 获取此请求对应的 Method 处理函数
|
||||
Method method = action.method().getMethod();
|
||||
|
||||
// 如果此 Method 或其所属 Class 标注了 @SaIgnore,则忽略掉鉴权
|
||||
if (SaStrategy.instance.isAnnotationPresent.apply(method, SaIgnore.class)) {
|
||||
// 注解校验
|
||||
try{
|
||||
Method method = action.method().getMethod();
|
||||
SaAnnotationStrategy.instance.checkMethodAnnotation.accept(method);
|
||||
} catch (StopMatchException ignored) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 注解校验
|
||||
SaStrategy.instance.checkMethodAnnotation.accept(method);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -15,18 +15,16 @@
|
||||
*/
|
||||
package cn.dev33.satoken.interceptor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.dev33.satoken.exception.BackResultException;
|
||||
import cn.dev33.satoken.exception.StopMatchException;
|
||||
import cn.dev33.satoken.fun.SaParamFunction;
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import cn.dev33.satoken.strategy.SaAnnotationStrategy;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Sa-Token 综合拦截器,提供注解鉴权和路由拦截鉴权能力
|
||||
@@ -96,18 +94,8 @@ public class SaInterceptor implements HandlerInterceptor {
|
||||
|
||||
// 这里必须确保 handler 是 HandlerMethod 类型时,才能进行注解鉴权
|
||||
if(isAnnotation && handler instanceof HandlerMethod) {
|
||||
|
||||
// 获取此请求对应的 Method 处理函数
|
||||
Method method = ((HandlerMethod) handler).getMethod();
|
||||
|
||||
// 如果此 Method 或其所属 Class 标注了 @SaIgnore,则忽略掉鉴权
|
||||
if(SaStrategy.instance.isAnnotationPresent.apply(method, SaIgnore.class)) {
|
||||
// 注意这里直接就退出整个鉴权了,最底部的 auth.run() 路由拦截鉴权也被跳出了
|
||||
return true;
|
||||
}
|
||||
|
||||
// 注解校验
|
||||
SaStrategy.instance.checkMethodAnnotation.accept(method);
|
||||
SaAnnotationStrategy.instance.checkMethodAnnotation.accept(method);
|
||||
}
|
||||
|
||||
// Auth 校验
|
||||
|
||||
Reference in New Issue
Block a user