From dfbac37d5eaec838dfeb67e987c8870deb1e02e5 Mon Sep 17 00:00:00 2001 From: orangej Date: Wed, 8 Sep 2021 10:59:56 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=9A=E5=9C=A8shiro?= =?UTF-8?q?=E6=8B=A6=E6=88=AA=E5=99=A8=E5=88=9D=E5=A7=8B=E5=8C=96=E6=97=B6?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=AF=B9=E5=BA=94=E6=96=B9=E6=B3=95=E7=9A=84?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=EF=BC=8C=E5=8F=96=E6=B6=88=E5=AF=B9=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E3=80=81actionKey=E7=9A=84=E5=80=9A=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../support/shiro/JbootShiroInterceptor.java | 7 +- .../support/shiro/JbootShiroManager.java | 108 ++++++++---------- .../jboot/support/shiro/JbootShiroUtil.java | 14 ++- .../shiro/ShiroInterceptorBuilder.java | 11 +- 4 files changed, 66 insertions(+), 74 deletions(-) diff --git a/src/main/java/io/jboot/support/shiro/JbootShiroInterceptor.java b/src/main/java/io/jboot/support/shiro/JbootShiroInterceptor.java index c3e34ec6..e2e41c9c 100644 --- a/src/main/java/io/jboot/support/shiro/JbootShiroInterceptor.java +++ b/src/main/java/io/jboot/support/shiro/JbootShiroInterceptor.java @@ -24,19 +24,18 @@ import io.jboot.support.shiro.processer.AuthorizeResult; */ public class JbootShiroInterceptor implements Interceptor { - @Override public void intercept(Invocation inv) { // 优先执行 onInvokeBefore,得到 AuthorizeResult - // 如果 AuthorizeResult 不为 null,则说用户自定义了其认证方式,比如 jwt、oss 等,此时直接返回给 onInvokeAfter - // 如果 AuthorizeResult 为 null,则有系统去执行(主要是去判断 Shiro 注解,然后通过对于的 Processer 去执行 ) + // 如果 AuthorizeResult 不为 null,则说明用户自定义了其认证方式,比如 jwt、oss 等,此时直接返回给 onInvokeAfter + // 如果 AuthorizeResult 为 null,则由系统去执行(主要是去判断 Shiro 注解,然后通过对应的 Processor 去执行 ) JbootShiroManager manager = JbootShiroManager.me(); AuthorizeResult result = manager.getInvokeListener().onInvokeBefore(inv); if (result == null) { - result = manager.invoke(inv.getActionKey()); + result = manager.invoke(inv); } if (result == null) { diff --git a/src/main/java/io/jboot/support/shiro/JbootShiroManager.java b/src/main/java/io/jboot/support/shiro/JbootShiroManager.java index b6a3bbf3..a5426544 100644 --- a/src/main/java/io/jboot/support/shiro/JbootShiroManager.java +++ b/src/main/java/io/jboot/support/shiro/JbootShiroManager.java @@ -15,11 +15,12 @@ */ package io.jboot.support.shiro; +import com.jfinal.aop.Invocation; import com.jfinal.config.Routes; import com.jfinal.core.Controller; import io.jboot.Jboot; -import io.jboot.support.shiro.processer.*; import io.jboot.exception.JbootIllegalConfigException; +import io.jboot.support.shiro.processer.*; import io.jboot.utils.ArrayUtil; import io.jboot.utils.ClassUtil; import io.jboot.utils.StrUtil; @@ -28,16 +29,19 @@ import org.apache.shiro.authz.annotation.*; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.List; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** * shiro 管理器. */ public class JbootShiroManager { - private static JbootShiroManager me = new JbootShiroManager(); + private final static JbootShiroManager me = new JbootShiroManager(); + + private final JbootShiroConfig jbootShiroConfig = Jboot.config(JbootShiroConfig.class); - private JbootShiroConfig jbootShiroConfig = Jboot.config(JbootShiroConfig.class); + private final ShiroRequiresAuthenticationProcesser requiresAuthenticationProcessor = new ShiroRequiresAuthenticationProcesser(); + private final ShiroRequiresUserProcesser requiresUserProcessor = new ShiroRequiresUserProcesser(); + private final ShiroRequiresGuestProcesser requiresGuestProcessor = new ShiroRequiresGuestProcesser(); private JbootShiroManager() { } @@ -51,74 +55,54 @@ public class JbootShiroManager { public void init(List routes) { - if (!jbootShiroConfig.isConfigOK()) { - return; - } - initInvokers(routes); + // do nothing } /** - * 初始化 invokers 变量 + * 根据类和方法上的注解生成shiro的注解处理器 + * + * @return 返回是否有shiro处理器,ShiroInterceptorBuilder 根据这一结果来决定是否对方法进行拦截 */ - private void initInvokers(List routes) { - Set excludedMethodName = JbootShiroUtil.buildExcludedMethodName(); - - ShiroRequiresAuthenticationProcesser requiresAuthenticationProcesser = new ShiroRequiresAuthenticationProcesser(); - ShiroRequiresUserProcesser requiresUserProcesser = new ShiroRequiresUserProcesser(); - ShiroRequiresGuestProcesser requiresGuestProcesser = new ShiroRequiresGuestProcesser(); - - - for (Routes.Route route : routes) { - Class controllerClass = route.getControllerClass(); - - String controllerKey = route.getControllerPath(); - - Annotation[] controllerAnnotations = controllerClass.getAnnotations(); - - Method[] methods = controllerClass.getMethods(); - for (Method method : methods) { - if (excludedMethodName.contains(method.getName())) { - continue; - } - - if (method.getAnnotation(ShiroClear.class) != null) { - continue; - } - - - Annotation[] methodAnnotations = method.getAnnotations(); - Annotation[] allAnnotations = ArrayUtil.concat(controllerAnnotations, methodAnnotations); - - - String actionKey = JbootShiroUtil.createActionKey(controllerClass, method, controllerKey); - ShiroAuthorizeProcesserInvoker invoker = new ShiroAuthorizeProcesserInvoker(); + public boolean buildShiroInvoker(Class clazz, Method method) { + if (Controller.class.isAssignableFrom(clazz) && + JbootShiroUtil.getControllerExcludedMethodName().contains(method.getName())) { + // 忽略 JbootController 中的方法 + return false; + } - for (Annotation annotation : allAnnotations) { - if (annotation.annotationType() == RequiresPermissions.class) { - ShiroRequiresPermissionsProcesser processer = new ShiroRequiresPermissionsProcesser((RequiresPermissions) annotation); - invoker.addProcesser(processer); - } else if (annotation.annotationType() == RequiresRoles.class) { - ShiroRequiresRolesProcesser processer = new ShiroRequiresRolesProcesser((RequiresRoles) annotation); - invoker.addProcesser(processer); - } else if (annotation.annotationType() == RequiresUser.class) { - invoker.addProcesser(requiresUserProcesser); - } else if (annotation.annotationType() == RequiresAuthentication.class) { - invoker.addProcesser(requiresAuthenticationProcesser); - } else if (annotation.annotationType() == RequiresGuest.class) { - invoker.addProcesser(requiresGuestProcesser); - } - } + if (method.getAnnotation(ShiroClear.class) != null) { + return false; + } - if (invoker.getProcessers() != null && invoker.getProcessers().size() > 0) { - invokers.put(actionKey, invoker); - } + Annotation[] allAnnotations = ArrayUtil.concat(clazz.getAnnotations(), method.getAnnotations()); + ShiroAuthorizeProcesserInvoker invoker = new ShiroAuthorizeProcesserInvoker(); + for (Annotation annotation : allAnnotations) { + if (annotation.annotationType() == RequiresPermissions.class) { + ShiroRequiresPermissionsProcesser processor = new ShiroRequiresPermissionsProcesser((RequiresPermissions) annotation); + invoker.addProcesser(processor); + } else if (annotation.annotationType() == RequiresRoles.class) { + ShiroRequiresRolesProcesser processor = new ShiroRequiresRolesProcesser((RequiresRoles) annotation); + invoker.addProcesser(processor); + } else if (annotation.annotationType() == RequiresUser.class) { + invoker.addProcesser(requiresUserProcessor); + } else if (annotation.annotationType() == RequiresAuthentication.class) { + invoker.addProcesser(requiresAuthenticationProcessor); + } else if (annotation.annotationType() == RequiresGuest.class) { + invoker.addProcesser(requiresGuestProcessor); } } - } + if (invoker.getProcessers() != null && invoker.getProcessers().size() > 0) { + invokers.put(method.toGenericString(), invoker); + return true; + } + + return false; + } - public AuthorizeResult invoke(String actionKey) { - ShiroAuthorizeProcesserInvoker invoker = invokers.get(actionKey); + public AuthorizeResult invoke(Invocation invocation) { + String key = invocation.getMethod().toGenericString(); + ShiroAuthorizeProcesserInvoker invoker = invokers.get(key); if (invoker == null) { return AuthorizeResult.ok(); } diff --git a/src/main/java/io/jboot/support/shiro/JbootShiroUtil.java b/src/main/java/io/jboot/support/shiro/JbootShiroUtil.java index 1af86a27..eba9bcb3 100644 --- a/src/main/java/io/jboot/support/shiro/JbootShiroUtil.java +++ b/src/main/java/io/jboot/support/shiro/JbootShiroUtil.java @@ -2,6 +2,7 @@ package io.jboot.support.shiro; import com.jfinal.core.ActionKey; import com.jfinal.core.Controller; +import io.jboot.web.controller.JbootController; import java.lang.reflect.Method; import java.util.HashSet; @@ -45,13 +46,16 @@ public class JbootShiroUtil { return actionKey; } + private static final Set excludedMethodName = new HashSet(); - public static Set buildExcludedMethodName() { - Set excludedMethodName = new HashSet(); - Method[] methods = Controller.class.getMethods(); - for (Method m : methods) { - excludedMethodName.add(m.getName()); + public static Set getControllerExcludedMethodName() { + if (excludedMethodName.isEmpty()) { + Method[] methods = JbootController.class.getMethods(); + for (Method m : methods) { + excludedMethodName.add(m.getName()); + } } + return excludedMethodName; } diff --git a/src/main/java/io/jboot/support/shiro/ShiroInterceptorBuilder.java b/src/main/java/io/jboot/support/shiro/ShiroInterceptorBuilder.java index f7c28779..56dacde2 100644 --- a/src/main/java/io/jboot/support/shiro/ShiroInterceptorBuilder.java +++ b/src/main/java/io/jboot/support/shiro/ShiroInterceptorBuilder.java @@ -28,13 +28,18 @@ import java.lang.reflect.Method; @AutoLoad public class ShiroInterceptorBuilder implements InterceptorBuilder { - private static JbootShiroConfig config = Jboot.config(JbootShiroConfig.class); + private static final JbootShiroConfig config = Jboot.config(JbootShiroConfig.class); @Override public void build(Class targetClass, Method method, Interceptors interceptors) { - if (Util.isController(targetClass) && config.isConfigOK()) { - interceptors.add(JbootShiroInterceptor.class); + if (config.isConfigOK() && + Util.isController(targetClass) // 暂时只对 controller 层的方法进行拦截 + ) { + boolean needIntercept = JbootShiroManager.me().buildShiroInvoker(targetClass, method); + if (needIntercept) { + interceptors.add(JbootShiroInterceptor.class); + } } } -- Gitee From b0808e9c90ba7ea11985234feaafe45f6203a8b6 Mon Sep 17 00:00:00 2001 From: orangej Date: Thu, 9 Sep 2021 10:38:17 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=AE=8C=E5=96=84shiro=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/base/JbootJunit4TestRunner.java | 16 ++++ .../io/jboot/test/base/JbootTestBase.java | 95 +++++++++++++++++++ .../io/jboot/test/shiro/ShiroController.java | 41 ++++++-- .../io/jboot/test/shiro/ShiroSupportTest.java | 79 +++++++++++++++ .../test/shiro/TestAuthenticationToken.java | 16 ---- .../io/jboot/test/shiro/TestShiroReam.java | 25 ++++- src/test/resources/jboot.properties | 2 + 7 files changed, 244 insertions(+), 30 deletions(-) create mode 100644 src/test/java/io/jboot/test/base/JbootJunit4TestRunner.java create mode 100644 src/test/java/io/jboot/test/base/JbootTestBase.java create mode 100644 src/test/java/io/jboot/test/shiro/ShiroSupportTest.java delete mode 100644 src/test/java/io/jboot/test/shiro/TestAuthenticationToken.java diff --git a/src/test/java/io/jboot/test/base/JbootJunit4TestRunner.java b/src/test/java/io/jboot/test/base/JbootJunit4TestRunner.java new file mode 100644 index 00000000..102c3a64 --- /dev/null +++ b/src/test/java/io/jboot/test/base/JbootJunit4TestRunner.java @@ -0,0 +1,16 @@ +package io.jboot.test.base; + +import com.jfinal.aop.Aop; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.InitializationError; + +public class JbootJunit4TestRunner extends BlockJUnit4ClassRunner { + public JbootJunit4TestRunner(Class testClass) throws InitializationError { + super(testClass); + } + + @Override + protected Object createTest() throws Exception { + return Aop.get(this.getTestClass().getJavaClass()); + } +} diff --git a/src/test/java/io/jboot/test/base/JbootTestBase.java b/src/test/java/io/jboot/test/base/JbootTestBase.java new file mode 100644 index 00000000..ab43a755 --- /dev/null +++ b/src/test/java/io/jboot/test/base/JbootTestBase.java @@ -0,0 +1,95 @@ +package io.jboot.test.base; + + +import com.jfinal.json.Json; +import io.jboot.app.JbootApplication; +import io.jboot.utils.HttpUtil; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.runner.RunWith; + +import java.net.ServerSocket; +import java.util.HashMap; +import java.util.Map; + +/** + * 测试基类,从随机端口启动jboot + */ +@Ignore +@RunWith(JbootJunit4TestRunner.class) +public class JbootTestBase { + + public static int PORT = 0; + public static String BASE_URL = String.format("http://localhost:%s", PORT); + + @BeforeClass + public synchronized static void startApp() { + if (PORT != 0) { + return; + } + + PORT = getAvailablePort(); + BASE_URL = String.format("http://localhost:%s", PORT); + JbootApplication.setBootArg("jboot.app.mode", "test"); + JbootApplication.setBootArg("undertow.port", PORT); + JbootApplication.setBootArg("undertow.ioThreads", 2); + + // 禁用undertow的dev模式,避免JbootTestRunner.createTest出现问题 + JbootApplication.setBootArg("undertow.devMode", false); + + JbootApplication.run(null); + } + + protected static int getAvailablePort() { + while (true) { + try { + ServerSocket socket = new ServerSocket(0); // 随机端口 + socket.close(); + Thread.sleep(50); // 等待端口完全关闭 + + return socket.getLocalPort(); + } catch (Exception ignore) { + } + } + } + + public static String httpGet(String url) { + return HttpUtil.httpGet(BASE_URL + url); + } + + public static String httpGet(String url, Map paras) { + return HttpUtil.httpGet(BASE_URL + url, paras); + } + + public static String httpGet(String url, Map paras, Map headers) { + return HttpUtil.httpGet(BASE_URL + url, paras, headers); + } + + public static String httpPost(String url) { + return HttpUtil.httpPost(BASE_URL + url, null, null, null); + } + + public static String httpPost(String url, String postData) { + return HttpUtil.httpPost(BASE_URL + url, null, null, postData); + } + + public static String httpPost(String url, Map paras) { + return HttpUtil.httpPost(BASE_URL + url, paras, null, null); + } + + public static String httpPost(String url, Map paras, String postData) { + return HttpUtil.httpPost(BASE_URL + url, paras, null, postData); + } + + public static String httpPost(String url, Map paras, Map headers, String postData) { + return HttpUtil.httpPost(BASE_URL + url, paras, headers, postData); + } + + public static String httpPostJson(String url, Object body) { + Map header = new HashMap<>(); + header.put("Content-Type", "application/json; charset=utf-8"); + + return HttpUtil.httpPost(BASE_URL + url, null, header, Json.getJson().toJson(body)); + } + +} diff --git a/src/test/java/io/jboot/test/shiro/ShiroController.java b/src/test/java/io/jboot/test/shiro/ShiroController.java index 87292940..6375bcf4 100644 --- a/src/test/java/io/jboot/test/shiro/ShiroController.java +++ b/src/test/java/io/jboot/test/shiro/ShiroController.java @@ -3,12 +3,16 @@ package io.jboot.test.shiro; import io.jboot.web.controller.JbootController; import io.jboot.web.controller.annotation.RequestMapping; +import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authz.annotation.RequiresAuthentication; import org.apache.shiro.authz.annotation.RequiresGuest; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.apache.shiro.authz.annotation.RequiresRoles; import org.apache.shiro.subject.Subject; -@RequestMapping(value = "/shiro",viewPath = "/htmls/shiro") +@RequestMapping(value = "/shiro", viewPath = "/htmls/shiro") public class ShiroController extends JbootController { @@ -16,37 +20,56 @@ public class ShiroController extends JbootController { renderText("index"); } - public void login(){ + public void login() { renderText("login"); } - public void doLogin(){ - + public void doLogin() { Subject subject = SecurityUtils.getSubject(); - subject.login(new TestAuthenticationToken()); + // 默认为admin登陆 + UsernamePasswordToken token = new UsernamePasswordToken(getPara("username", "admin"), "123"); + subject.login(token); // subject.isAuthenticated(); // subject.isPermitted() renderText("logined success"); - } - public void logout(){ + public void logout() { Subject subject = SecurityUtils.getSubject(); subject.logout(); renderText("logouted success"); } @RequiresAuthentication - public void usercenter(){ + public void usercenter() { renderText("usercenter"); } @RequiresGuest - public void guest(){ + public void guest() { renderText("guest"); } + @RequiresRoles("editor") + public void editor() { + renderText("editor"); + } + + @RequiresRoles("admin") + public void admin() { + renderText("admin"); + } + + @RequiresPermissions("all:read") + public void readAll() { + renderText("all"); + } + + @RequiresPermissions("news:read") + public void readNews() { + renderText("news"); + } } diff --git a/src/test/java/io/jboot/test/shiro/ShiroSupportTest.java b/src/test/java/io/jboot/test/shiro/ShiroSupportTest.java new file mode 100644 index 00000000..71127132 --- /dev/null +++ b/src/test/java/io/jboot/test/shiro/ShiroSupportTest.java @@ -0,0 +1,79 @@ +package io.jboot.test.shiro; + +import io.jboot.components.http.JbootHttpRequest; +import io.jboot.components.http.JbootHttpResponse; +import io.jboot.test.base.JbootTestBase; +import io.jboot.utils.HttpUtil; +import io.jboot.utils.StrUtil; +import org.junit.Test; + + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + + +public class ShiroSupportTest extends JbootTestBase { + + + @Test + public void test() { + // 不需要登录的页面 + assertEquals("index", httpGet("/shiro")); + + // 未登陆,重定向到 /shiro/loing + assertEquals("login", httpGet("/shiro/usercenter")); + + // 使用 admin 账号登录 + String userCookie = loginWith("admin"); + + // 使用 cookie 访问 usercenter + assertEquals("usercenter", getWithCookie("/shiro/usercenter", userCookie)); + + // 访问 admin 相关的页面 + assertEquals("admin", getWithCookie("/shiro/admin", userCookie)); + assertEquals("all", getWithCookie("/shiro/readAll", userCookie)); + + // 访问 editor 页面受限 + assertTrue(getWithCookie("/shiro/editor", userCookie).contains("403")); + assertTrue(getWithCookie("/shiro/readNews", userCookie).contains("403")); + + // 退出登陆 + assertEquals("logouted success", getWithCookie("/shiro/logout", userCookie)); + + // 再次访问 usercenter,重定向到 login + assertEquals("login", getWithCookie("/shiro/usercenter", userCookie)); + + // 使用 editor 登陆 + userCookie = loginWith("editor"); + assertEquals("editor", getWithCookie("/shiro/editor", userCookie)); + assertEquals("news", getWithCookie("/shiro/readNews", userCookie)); + + assertTrue(getWithCookie("/shiro/admin", userCookie).contains("403")); + assertTrue(getWithCookie("/shiro/readAll", userCookie).contains("403")); + } + + /** + * 使用指定的cookie信息,访问url + */ + private String getWithCookie(String url, String cookie) { + JbootHttpRequest req = JbootHttpRequest.create(BASE_URL + url, null, JbootHttpRequest.METHOD_GET); + req.addHeader("Cookie", cookie); + JbootHttpResponse rsp = HttpUtil.handle(req); + return rsp.getContent(); + } + + /** + * 使用指定用户名登录,返回cookie信息 + */ + private String loginWith(String username) { + Map params = new HashMap<>(); + params.put("username", username); + JbootHttpRequest req = JbootHttpRequest.create(BASE_URL + "/shiro/doLogin", params, JbootHttpRequest.METHOD_GET); + + JbootHttpResponse rsp = HttpUtil.handle(req); + assertEquals("logined success", rsp.getContent()); + return StrUtil.join(rsp.getHeaders().get("Set-Cookie"), ";"); + } +} diff --git a/src/test/java/io/jboot/test/shiro/TestAuthenticationToken.java b/src/test/java/io/jboot/test/shiro/TestAuthenticationToken.java deleted file mode 100644 index e4308181..00000000 --- a/src/test/java/io/jboot/test/shiro/TestAuthenticationToken.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.jboot.test.shiro; - -import org.apache.shiro.authc.AuthenticationToken; - - -public class TestAuthenticationToken implements AuthenticationToken { - @Override - public Object getPrincipal() { - return "Principal"; - } - - @Override - public Object getCredentials() { - return "Credentials"; - } -} diff --git a/src/test/java/io/jboot/test/shiro/TestShiroReam.java b/src/test/java/io/jboot/test/shiro/TestShiroReam.java index a653c248..d8849031 100644 --- a/src/test/java/io/jboot/test/shiro/TestShiroReam.java +++ b/src/test/java/io/jboot/test/shiro/TestShiroReam.java @@ -4,15 +4,19 @@ import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.SimpleAuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.realm.Realm; +import org.apache.shiro.subject.PrincipalCollection; -public class TestShiroReam implements Realm { +public class TestShiroReam extends AuthorizingRealm { @Override public String getName() { System.out.println("MyRealm.getName()"); - return null; + return "TestShiroReam"; } @Override @@ -22,9 +26,20 @@ public class TestShiroReam implements Realm { } @Override - public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { - System.out.println("MyRealm.getAuthenticationInfo" + token); - return new SimpleAuthenticationInfo("1", "2", "3"); + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { + return new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), getName()); } + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { + String username = (String) principalCollection.getPrimaryPrincipal(); + SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); + info.addRole(username); // admin | editor + if ("admin".equalsIgnoreCase(username)) { + info.addStringPermission("all:read"); + } else if ("editor".equalsIgnoreCase(username)) { + info.addStringPermission("news:read"); + } + return info; + } } \ No newline at end of file diff --git a/src/test/resources/jboot.properties b/src/test/resources/jboot.properties index 0b31d369..345f5600 100644 --- a/src/test/resources/jboot.properties +++ b/src/test/resources/jboot.properties @@ -61,3 +61,5 @@ jboot.sentinel.enable = true #jboot.sentinel.datasource = redis #jboot.sentinel.datasource.redis.host = 127.0.0.1 #jboot.sentinel.datasource.redis.database = 1 +jboot.shiro.ini=shiro.ini +jboot.shiro.loginUrl=/shiro/login \ No newline at end of file -- Gitee