shiro常用注解和过滤器,编写自定义注解实现 anon 所有人访问功能

1. 注解

shiro常用注解和过滤器,编写自定义注解实现 anon 所有人访问功能_第1张图片
已登录,未记住我,重开浏览器之后,就成了未登录

@RequiresGuest:未登录可以访问;认证过或使用记住我功能拒绝访问
@RequiresAuthentication: 认证过可以访问,其他时候拒绝访问
@RequiresUser: 认证过或使用记住我功能可以访问
@RequiresPermissions(value = {“user:create”, “user:update”}, logical = Logical.AND)
同时具备2个权限才能访问
@RequiresPermissions(value = {“user:create”, “user:update”}, logical = Logical.OR)
拥有其中任意一个权限就可以访问
@RequiresRoles 跟 @RequiresPermissions 使用差不多的

2. 过滤器

shiro常用注解和过滤器,编写自定义注解实现 anon 所有人访问功能_第2张图片

3. 自定义注解

一般做法:ShiroFilterFactoryBean 中设置 filterChainDefinitionMap 如图:
shiro常用注解和过滤器,编写自定义注解实现 anon 所有人访问功能_第3张图片
一旦接口发生了变更就得重新写一下接口路径,这很麻烦,于是编写自定义注解完成这个繁琐的操作

正片开始
思路:自定义注解@Anon 通过反射获取所有标记这个注解的接口,然后加入filterChainDefinitionMap

3.1 自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Anon {
}

3.2 JwtFilter中处理

public class JwtFilter extends BasicHttpAuthenticationFilter {

	/**
     * 执行登录认证
     *
     * 在ShiroConfig中获取全部的接口 会导致aop失效
     *    原因:controller 和 service 被提前实例化,导致这些类不会被 BeanPostProcessor 代理,从而导致部分 aop 功能失效
     *    分析:获取所有接口的目的在于判断这个接口是否标记了 Anon 注解,也就是是否能够机型匿名访问
     *         之前是提前获取接口添加到 filterChainDefinitionMap 从而实现匿名访问
     *         JwtFilter是认证的入口,并且所有请求都会到达这里,在这里进行判断就可以避免上述问题的发生
     *    解决:通过处理器适配器获取 handler 及目标类的目标方法,判断是否包含 Anon 注解
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        WebApplicationContext applicationContext = RequestContextUtils.findWebApplicationContext(httpServletRequest);
        RequestMappingHandlerMapping handlerMapping = applicationContext.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
        HandlerExecutionChain handler = null;
        try {
            handler = handlerMapping.getHandler(httpServletRequest);
            Annotation[] declaredAnnotations = ((HandlerMethod) handler.getHandler()).
                    getMethod().getDeclaredAnnotations();
            for(Annotation annotation:declaredAnnotations){
                if(Anon.class.equals(annotation.annotationType())){
                    return true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        executeLogin(request, response);
        return true;
    }
}

你可能感兴趣的:(java,开发语言)