mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-09-19 10:08:07 +08:00
新增 jboot,jfinal项目的运行插件
This commit is contained in:
55
sa-token-starter/sa-token-jboot-plugin/pom.xml
Normal file
55
sa-token-starter/sa-token-jboot-plugin/pom.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>sa-token-starter</artifactId>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<version>1.28.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>sa-token-jboot-plugin</artifactId>
|
||||
<description>jboot integrate sa-token</description>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.jboot</groupId>
|
||||
<artifactId>jboot</artifactId>
|
||||
<version>3.11.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-core</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-servlet</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
<compilerArgument>-parameters</compilerArgument>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@@ -0,0 +1,60 @@
|
||||
package cn.dev33.satoken.jboot;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PathAnalyzer {
|
||||
|
||||
private static Map<String, PathAnalyzer> cached = new LinkedHashMap();
|
||||
private Pattern pattern;
|
||||
|
||||
public static PathAnalyzer get(String expr) {
|
||||
PathAnalyzer pa = (PathAnalyzer)cached.get(expr);
|
||||
if (pa == null) {
|
||||
synchronized(expr.intern()) {
|
||||
pa = (PathAnalyzer)cached.get(expr);
|
||||
if (pa == null) {
|
||||
pa = new PathAnalyzer(expr);
|
||||
cached.put(expr, pa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pa;
|
||||
}
|
||||
|
||||
private PathAnalyzer(String expr) {
|
||||
this.pattern = Pattern.compile(exprCompile(expr), 2);
|
||||
}
|
||||
|
||||
public Matcher matcher(String uri) {
|
||||
return this.pattern.matcher(uri);
|
||||
}
|
||||
|
||||
public boolean matches(String uri) {
|
||||
return this.pattern.matcher(uri).find();
|
||||
}
|
||||
|
||||
private static String exprCompile(String expr) {
|
||||
String p = expr.replace(".", "\\.");
|
||||
p = p.replace("$", "\\$");
|
||||
p = p.replace("**", ".[]");
|
||||
p = p.replace("*", "[^/]*");
|
||||
if (p.indexOf("{") >= 0) {
|
||||
if (p.indexOf("_}") > 0) {
|
||||
p = p.replaceAll("\\{[^\\}]+?\\_\\}", "(.+?)");
|
||||
}
|
||||
|
||||
p = p.replaceAll("\\{[^\\}]+?\\}", "([^/]+?)");
|
||||
}
|
||||
|
||||
if (!p.startsWith("/")) {
|
||||
p = "/" + p;
|
||||
}
|
||||
|
||||
p = p.replace(".[]", ".*");
|
||||
return "^" + p + "$";
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package cn.dev33.satoken.jboot;
|
||||
|
||||
import cn.dev33.satoken.strategy.SaStrategy;
|
||||
import com.jfinal.aop.Interceptor;
|
||||
import com.jfinal.aop.Invocation;
|
||||
|
||||
/**
|
||||
* 注解式鉴权 - 拦截器
|
||||
*/
|
||||
public class SaAnnotationInterceptor implements Interceptor {
|
||||
@Override
|
||||
public void intercept(Invocation invocation) {
|
||||
SaStrategy.me.checkMethodAnnotation.accept((invocation.getMethod()));
|
||||
invocation.invoke();
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
package cn.dev33.satoken.jboot;
|
||||
|
||||
import cn.dev33.satoken.context.SaTokenContext;
|
||||
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.servlet.model.SaRequestForServlet;
|
||||
import cn.dev33.satoken.servlet.model.SaResponseForServlet;
|
||||
import cn.dev33.satoken.servlet.model.SaStorageForServlet;
|
||||
import io.jboot.web.controller.JbootControllerContext;
|
||||
|
||||
/**
|
||||
* Sa-Token 上下文处理器 [Jboot 版本实现]
|
||||
*/
|
||||
public class SaTokenContextForJboot implements SaTokenContext {
|
||||
/**
|
||||
* 获取当前请求的Request对象
|
||||
*/
|
||||
@Override
|
||||
public SaRequest getRequest() {
|
||||
return new SaRequestForServlet(JbootControllerContext.get().getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的Response对象
|
||||
*/
|
||||
@Override
|
||||
public SaResponse getResponse() {
|
||||
return new SaResponseForServlet(JbootControllerContext.get().getResponse());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前请求的 [存储器] 对象
|
||||
*/
|
||||
@Override
|
||||
public SaStorage getStorage() {
|
||||
return new SaStorageForServlet(JbootControllerContext.get().getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验指定路由匹配符是否可以匹配成功指定路径
|
||||
*/
|
||||
@Override
|
||||
public boolean matchPath(String pattern, String path) {
|
||||
return PathAnalyzer.get(pattern).matches(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return SaTokenContext.super.isValid();
|
||||
}
|
||||
}
|
@@ -0,0 +1,219 @@
|
||||
package cn.dev33.satoken.jboot;
|
||||
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import io.jboot.Jboot;
|
||||
import io.jboot.components.cache.redis.JbootRedisCacheConfig;
|
||||
import io.jboot.exception.JbootIllegalConfigException;
|
||||
import io.jboot.support.redis.JbootRedis;
|
||||
import io.jboot.support.redis.JbootRedisManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SaTokenDaoRedis implements SaTokenDao {
|
||||
|
||||
private final JbootRedis redis;
|
||||
/**
|
||||
* 标记:是否已初始化成功
|
||||
*/
|
||||
public boolean isInit;
|
||||
|
||||
public SaTokenDaoRedis(){
|
||||
JbootRedisCacheConfig redisConfig = Jboot.config(JbootRedisCacheConfig.class);
|
||||
|
||||
//优先使用 jboot.cache.redis 的配置
|
||||
if (redisConfig.isConfigOk()) {
|
||||
redis = JbootRedisManager.me().getRedis(redisConfig);
|
||||
}
|
||||
// 当 jboot.cache.redis 配置不存在时,
|
||||
// 使用 jboot.redis 的配置
|
||||
else {
|
||||
redis = Jboot.getRedis();
|
||||
}
|
||||
|
||||
if (redis == null) {
|
||||
this.isInit = false;
|
||||
throw new JbootIllegalConfigException("can not get redis, please check your jboot.properties , please correct config jboot.cache.redis.host or jboot.redis.host ");
|
||||
}else{
|
||||
this.isInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Value,如无返空
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String get(String key) {
|
||||
return redis.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入Value,并设定存活时间 (单位: 秒)
|
||||
* @param key
|
||||
* @param value
|
||||
* @param timeout
|
||||
*/
|
||||
@Override
|
||||
public void set(String key, String value, long timeout) {
|
||||
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
||||
redis.set(key, value);
|
||||
}else{
|
||||
redis.setex(key,Integer.parseInt(timeout+""),value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改指定key-value键值对 (过期时间不变)
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
@Override
|
||||
public void update(String key, String value) {
|
||||
long expire = getTimeout(key);
|
||||
// -2 = 无此键
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
this.set(key,value,expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除Value
|
||||
* @param key
|
||||
*/
|
||||
@Override
|
||||
public void delete(String key) {
|
||||
redis.del(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Value的剩余存活时间 (单位: 秒)
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public long getTimeout(String key) {
|
||||
return redis.ttl(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改Value的剩余存活时间 (单位: 秒)
|
||||
* @param key
|
||||
* @param timeout
|
||||
*/
|
||||
@Override
|
||||
public void updateTimeout(String key, long timeout) {
|
||||
//判断是否想要设置为永久
|
||||
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
||||
long expire = getTimeout(key);
|
||||
if(expire == SaTokenDao.NEVER_EXPIRE) {
|
||||
// 如果其已经被设置为永久,则不作任何处理
|
||||
} else {
|
||||
// 如果尚未被设置为永久,那么再次set一次
|
||||
this.set(key, this.get(key), timeout);
|
||||
}
|
||||
return;
|
||||
}
|
||||
redis.expire(key,Integer.parseInt(timeout+""));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Object,如无返空
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Object getObject(String key) {
|
||||
return redis.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入Object,并设定存活时间 (单位: 秒)
|
||||
* @param key
|
||||
* @param object
|
||||
* @param timeout
|
||||
*/
|
||||
@Override
|
||||
public void setObject(String key, Object object, long timeout) {
|
||||
if(timeout == 0 || timeout <= SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
||||
redis.set(key, object);
|
||||
}else{
|
||||
redis.setex(key,Integer.parseInt(timeout+""),object);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新Object (过期时间不变)
|
||||
* @param key
|
||||
* @param object
|
||||
*/
|
||||
@Override
|
||||
public void updateObject(String key, Object object) {
|
||||
long expire = getObjectTimeout(key);
|
||||
// -2 = 无此键
|
||||
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
|
||||
return;
|
||||
}
|
||||
this.setObject(key, object, expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除Object
|
||||
* @param key
|
||||
*/
|
||||
@Override
|
||||
public void deleteObject(String key) {
|
||||
redis.del(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getObjectTimeout(String key) {
|
||||
return redis.ttl(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改Object的剩余存活时间 (单位: 秒)
|
||||
* @param key
|
||||
* @param timeout
|
||||
*/
|
||||
@Override
|
||||
public void updateObjectTimeout(String key, long timeout) {
|
||||
//判断是否想要设置为永久
|
||||
if(timeout == SaTokenDao.NEVER_EXPIRE) {
|
||||
long expire = getTimeout(key);
|
||||
if(expire == SaTokenDao.NEVER_EXPIRE) {
|
||||
// 如果其已经被设置为永久,则不作任何处理
|
||||
} else {
|
||||
// 如果尚未被设置为永久,那么再次set一次
|
||||
this.set(key, this.get(key), timeout);
|
||||
}
|
||||
return;
|
||||
}
|
||||
redis.expire(key,Integer.parseInt(timeout+""));
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索数据
|
||||
* @param prefix
|
||||
* @param keyword
|
||||
* @param start
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<String> searchData(String prefix, String keyword, int start, int size) {
|
||||
Set<String> keys = redis.keys(prefix + "*" + keyword + "*");
|
||||
List<String> list = new ArrayList<String>(keys);
|
||||
return SaFoxUtil.searchList(list, start, size);
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package cn.dev33.satoken.jboot.test;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import io.jboot.app.JbootApplication;
|
||||
import io.jboot.web.controller.JbootController;
|
||||
import io.jboot.web.controller.annotation.RequestMapping;
|
||||
|
||||
@RequestMapping("/")
|
||||
public class AppRun extends JbootController {
|
||||
public static void main(String[] args) {
|
||||
JbootApplication.run(args);
|
||||
}
|
||||
|
||||
public void index(){
|
||||
renderText("index");
|
||||
}
|
||||
|
||||
public void doLogin(){
|
||||
StpUtil.login(10001);
|
||||
//赋值角色
|
||||
renderText("登录成功");
|
||||
}
|
||||
|
||||
public void getLoginInfo(){
|
||||
System.out.println("是否登录:"+StpUtil.isLogin());
|
||||
System.out.println("登录信息"+StpUtil.getTokenInfo());
|
||||
renderJson(StpUtil.getTokenInfo());
|
||||
}
|
||||
|
||||
@SaCheckRole("super-admin")
|
||||
public void add(){
|
||||
renderText("超级管理员方法!");
|
||||
}
|
||||
}
|
@@ -0,0 +1,77 @@
|
||||
package cn.dev33.satoken.jboot.test;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
import cn.dev33.satoken.context.SaTokenContext;
|
||||
import com.jfinal.config.Constants;
|
||||
import com.jfinal.config.Interceptors;
|
||||
import com.jfinal.config.Routes;
|
||||
import com.jfinal.template.Engine;
|
||||
import cn.dev33.satoken.jboot.SaAnnotationInterceptor;
|
||||
import cn.dev33.satoken.jboot.SaTokenContextForJboot;
|
||||
import cn.dev33.satoken.jboot.SaTokenDaoRedis;
|
||||
import io.jboot.aop.jfinal.JfinalHandlers;
|
||||
import io.jboot.aop.jfinal.JfinalPlugins;
|
||||
import io.jboot.core.listener.JbootAppListener;
|
||||
|
||||
public class AtteStartListener implements JbootAppListener {
|
||||
public void onInit() {
|
||||
//注册权限验证功能,由saToken处理请求上下文
|
||||
SaTokenContext saTokenContext = new SaTokenContextForJboot();
|
||||
SaManager.setSaTokenContext(saTokenContext);
|
||||
//加载权限角色设置数据接口
|
||||
SaManager.setStpInterface(new StpInterfaceImpl());
|
||||
//增加redis缓存,需要先配置redis地址
|
||||
// SaManager.setSaTokenDao(new SaTokenDaoRedis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConstantConfig(Constants constants) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRouteConfig(Routes routes) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEngineConfig(Engine engine) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginConfig(JfinalPlugins plugins) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInterceptorConfig(Interceptors interceptors) {
|
||||
//开启注解方式权限验证
|
||||
interceptors.add(new SaAnnotationInterceptor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHandlerConfig(JfinalHandlers handlers) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartBefore() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartFinish() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package cn.dev33.satoken.jboot.test;
|
||||
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import io.jboot.aop.annotation.Bean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Bean
|
||||
public class StpInterfaceImpl implements StpInterface {
|
||||
@Override
|
||||
public List<String> getPermissionList(Object o, String s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRoleList(Object o, String s) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("admin");
|
||||
list.add("super-admin");
|
||||
return list;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user