diff --git a/diboot-example/src/main/java/com/diboot/example/controller/AuthorizationWrapperController.java b/diboot-example/src/main/java/com/diboot/example/controller/AuthorizationWrapperController.java new file mode 100644 index 0000000..cfdba8f --- /dev/null +++ b/diboot-example/src/main/java/com/diboot/example/controller/AuthorizationWrapperController.java @@ -0,0 +1,40 @@ +package com.diboot.example.controller; + +import com.diboot.core.vo.JsonResult; +import com.diboot.shiro.authz.annotation.AuthorizationPrefix; +import com.diboot.shiro.authz.annotation.AuthorizationWrapper; +import org.apache.shiro.authz.annotation.Logical; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 权限测试 + * @author : wee + * @version : v 2.0 + * @Date 2019-06-19 13:37 + */ +@RestController +@RequestMapping("/authorization") +@AuthorizationPrefix(name = "测试权限", code = "authorization", prefix = "authorization") +public class AuthorizationWrapperController { + + /**此处权限为:authorization:get 或 authorization:test*/ + @GetMapping("/get") + @AuthorizationWrapper(value = @RequiresPermissions(value = {"get", "test"}, + logical = Logical.OR), + name = {"查看", "测试"}) + public JsonResult get() { + return new JsonResult("ok"); + } + + /**此处权限为:getAll 或 test*/ + @GetMapping("/getAll") + @AuthorizationWrapper(value = @RequiresPermissions({"getAll", "test"}), + name = {"获取所有", "测试"}, + ignorePrefix = true) + public JsonResult getAll() { + return new JsonResult("ok"); + } +} diff --git a/diboot-example/src/main/java/com/diboot/example/listener/ExampleListener.java b/diboot-example/src/main/java/com/diboot/example/listener/ExampleListener.java new file mode 100644 index 0000000..74efa36 --- /dev/null +++ b/diboot-example/src/main/java/com/diboot/example/listener/ExampleListener.java @@ -0,0 +1,36 @@ +package com.diboot.example.listener; + +import com.diboot.shiro.authz.storage.EnableStorageEnum; +import com.diboot.shiro.listener.AbstractStorageApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +/** + * 示例监听器 + * {@link AbstractStorageApplicationListener}丰富了 {@link org.springframework.context.ApplicationListener} + * {@link AbstractStorageApplicationListener}中封装了将{@link com.diboot.shiro.authz.annotation.AuthorizationWrapper}权限自动入库的操作 + * 当你使用注解{@link com.diboot.shiro.authz.annotation.AuthorizationWrapper},建议直接继承{@link AbstractStorageApplicationListener} + * 然后对{@link AbstractStorageApplicationListener#customExecute(ContextRefreshedEvent)}方法进行重写 + * 注:需要手动设置一个默认构造函数,传递是否自动权限入库 + * @author : wee + * @version : v 2.0 + * @Date 2019-06-18 23:11 + */ +@Component +public class ExampleListener extends AbstractStorageApplicationListener { + + /**需要手动实现构造来设置是否开启权限入库操作,默认入库*/ + protected ExampleListener() { + super(EnableStorageEnum.TRUE); + } + + /** + * 系统启动后,客户自定义事件 + * + * @param event + */ + @Override + protected void customExecute(ContextRefreshedEvent event) { + System.out.println("============00000000"); + } +} diff --git a/diboot-shiro/src/main/java/com/diboot/shiro/authz/annotation/AuthorizationPrefix.java b/diboot-shiro/src/main/java/com/diboot/shiro/authz/annotation/AuthorizationPrefix.java new file mode 100644 index 0000000..5d9b8aa --- /dev/null +++ b/diboot-shiro/src/main/java/com/diboot/shiro/authz/annotation/AuthorizationPrefix.java @@ -0,0 +1,45 @@ +package com.diboot.shiro.authz.annotation; + +import java.lang.annotation.*; + +/** + * 权限注解的前缀,用于controller注解
+ * 注:当你使用{@link AuthorizationWrapper},请在类上使用{@link AuthorizationPrefix}注解进行标记,系统启动的时候才会将权限入库 + * @author : wee + * @version v 2.0 + * @Date 2019-06-17 20:42 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface AuthorizationPrefix { + + /** + * 名称 + * + * 设置当前权限前缀名称 + * @return + */ + String name(); + + /** + * 编码 + * + * 设置当前权限前缀编码 + * @return + */ + String code(); + + /** + *

{@link AuthorizationWrapper#requiresPermissions()#value()}的前缀

+ * + * 注:当前注解优先级低于{@link AuthorizationWrapper#prefix()}, + * 如果两者都配置优先使用{@link AuthorizationWrapper#prefix()} + * @return + */ + String prefix() default ""; +} diff --git a/diboot-shiro/src/main/java/com/diboot/shiro/authz/annotation/AuthorizationWrapper.java b/diboot-shiro/src/main/java/com/diboot/shiro/authz/annotation/AuthorizationWrapper.java new file mode 100644 index 0000000..eb7864b --- /dev/null +++ b/diboot-shiro/src/main/java/com/diboot/shiro/authz/annotation/AuthorizationWrapper.java @@ -0,0 +1,28 @@ +package com.diboot.shiro.authz.annotation; + +import org.apache.shiro.authz.annotation.*; + +import java.lang.annotation.*; + +/** + * 权限包装:目前只包装{@link RequiresPermissions},可以根据需要包装{@link RequiresRoles} + * @author : wee + * @version v 1.0 + * @Date 2019-06-19 00:40 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface AuthorizationWrapper { + + /**RequiresPermissions包装*/ + RequiresPermissions value(); + + /**权限别名:用于存储到数据库,与{@link RequiresPermissions#value()}的值一一对应*/ + String[] name(); + + /**设置前缀:用于拼接,详细描述参考{@link AuthorizationPrefix#prefix()}*/ + String prefix() default ""; + + /**是否忽略前缀:默认不忽略*/ + boolean ignorePrefix() default false; +} diff --git a/diboot-shiro/src/main/java/com/diboot/shiro/authz/aop/AuthorizationWrapperAnnotationMethodInterceptor.java b/diboot-shiro/src/main/java/com/diboot/shiro/authz/aop/AuthorizationWrapperAnnotationMethodInterceptor.java new file mode 100644 index 0000000..bc02dda --- /dev/null +++ b/diboot-shiro/src/main/java/com/diboot/shiro/authz/aop/AuthorizationWrapperAnnotationMethodInterceptor.java @@ -0,0 +1,50 @@ +package com.diboot.shiro.authz.aop; + +import com.diboot.shiro.authz.annotation.AuthorizationWrapper; +import com.diboot.shiro.authz.handler.AuthorizationWrapperAnnotationHandler; +import org.apache.shiro.aop.AnnotationResolver; +import org.apache.shiro.aop.MethodInvocation; +import org.apache.shiro.authz.AuthorizationException; +import org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor; + +/** + * {@link AuthorizationWrapper} 拦截器 + * @author : wee + * @version : v2.0 + * @Date 2019-06-14 22:19 + */ +public class AuthorizationWrapperAnnotationMethodInterceptor extends AuthorizingAnnotationMethodInterceptor { + /** + * Default no-argument constructor that ensures this interceptor looks for + * {@link AuthorizationWrapper AuthorizationWrapper} annotations in a method declaration. + */ + public AuthorizationWrapperAnnotationMethodInterceptor() { + super( new AuthorizationWrapperAnnotationHandler() ); + } + + /** + * @param resolver + * @since 1.1 + */ + public AuthorizationWrapperAnnotationMethodInterceptor(AnnotationResolver resolver) { + super( new AuthorizationWrapperAnnotationHandler(), resolver); + } + + /** + * 当使用AuthorizationWrapper注解进行权限验证的时候,自动的去追加前缀 + * @param mi + * @throws AuthorizationException + */ + @Override + public void assertAuthorized(MethodInvocation mi) throws AuthorizationException { + try { + ((AuthorizationWrapperAnnotationHandler)getHandler()).assertAuthorized(getResolver(), mi); + } + catch(AuthorizationException ae) { + if (ae.getCause() == null) { + ae.initCause(new AuthorizationException("Not authorized to invoke method: " + mi.getMethod())); + } + throw ae; + } + } +} diff --git a/diboot-shiro/src/main/java/com/diboot/shiro/bind/aop/CustomAopAllianceAnnotationsAuthorizingMethodInterceptor.java b/diboot-shiro/src/main/java/com/diboot/shiro/authz/aop/CustomAopAllianceAnnotationsAuthorizingMethodInterceptor.java similarity index 95% rename from diboot-shiro/src/main/java/com/diboot/shiro/bind/aop/CustomAopAllianceAnnotationsAuthorizingMethodInterceptor.java rename to diboot-shiro/src/main/java/com/diboot/shiro/authz/aop/CustomAopAllianceAnnotationsAuthorizingMethodInterceptor.java index 929d5ef..4d6bc49 100644 --- a/diboot-shiro/src/main/java/com/diboot/shiro/bind/aop/CustomAopAllianceAnnotationsAuthorizingMethodInterceptor.java +++ b/diboot-shiro/src/main/java/com/diboot/shiro/authz/aop/CustomAopAllianceAnnotationsAuthorizingMethodInterceptor.java @@ -1,6 +1,5 @@ -package com.diboot.shiro.bind.aop; +package com.diboot.shiro.authz.aop; -import com.diboot.shiro.bind.aop.PermissionWrapperAnnotationMethodInterceptor; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.shiro.aop.AnnotationResolver; @@ -12,6 +11,7 @@ import java.util.ArrayList; import java.util.List; /** + * 自定义AOP拦截 * @author : wee * @version : v2.0 * @Date 2019-06-15 12:07 @@ -21,7 +21,7 @@ public class CustomAopAllianceAnnotationsAuthorizingMethodInterceptor extends An List interceptors = new ArrayList(6); AnnotationResolver resolver = new SpringAnnotationResolver(); - interceptors.add(new PermissionWrapperAnnotationMethodInterceptor(resolver)); + interceptors.add(new AuthorizationWrapperAnnotationMethodInterceptor(resolver)); interceptors.add(new RoleAnnotationMethodInterceptor(resolver)); interceptors.add(new PermissionAnnotationMethodInterceptor(resolver)); interceptors.add(new AuthenticatedAnnotationMethodInterceptor(resolver)); diff --git a/diboot-shiro/src/main/java/com/diboot/shiro/bind/aop/CustomAuthorizationAttributeSourceAdvisor.java b/diboot-shiro/src/main/java/com/diboot/shiro/authz/aop/CustomAuthorizationAttributeSourceAdvisor.java similarity index 93% rename from diboot-shiro/src/main/java/com/diboot/shiro/bind/aop/CustomAuthorizationAttributeSourceAdvisor.java rename to diboot-shiro/src/main/java/com/diboot/shiro/authz/aop/CustomAuthorizationAttributeSourceAdvisor.java index 86c32f7..52a46e6 100644 --- a/diboot-shiro/src/main/java/com/diboot/shiro/bind/aop/CustomAuthorizationAttributeSourceAdvisor.java +++ b/diboot-shiro/src/main/java/com/diboot/shiro/authz/aop/CustomAuthorizationAttributeSourceAdvisor.java @@ -1,6 +1,6 @@ -package com.diboot.shiro.bind.aop; +package com.diboot.shiro.authz.aop; -import com.diboot.shiro.bind.annotation.RequiresPermissionsWrapper; +import com.diboot.shiro.authz.annotation.AuthorizationWrapper; import org.apache.shiro.authz.annotation.*; import org.apache.shiro.mgt.SecurityManager; import org.slf4j.Logger; @@ -12,6 +12,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; /** + * 自定义切片装配器 * @author : wee * @version : v1.0 * @Date 2019-06-15 12:27 @@ -22,7 +23,7 @@ public class CustomAuthorizationAttributeSourceAdvisor extends StaticMethodMatch private static final Class[] AUTHZ_ANNOTATION_CLASSES = new Class[] { - RequiresPermissionsWrapper.class, + AuthorizationWrapper.class, RequiresPermissions.class, RequiresRoles.class, RequiresUser.class, RequiresGuest.class, RequiresAuthentication.class }; @@ -48,7 +49,7 @@ public class CustomAuthorizationAttributeSourceAdvisor extends StaticMethodMatch * Returns true if the method or the class has any Shiro annotations, false otherwise. * The annotations inspected are: *