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

文章介绍了如何在Shiro框架中使用自定义注解Anon,以简化接口路径的管理,并在JwtFilter中处理匿名访问逻辑,通过处理器适配器判断方法是否有Anon注解,从而避免AOP失效问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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. 过滤器

在这里插入图片描述

3. 自定义注解

一般做法:ShiroFilterFactoryBean 中设置 filterChainDefinitionMap 如图:
在这里插入图片描述
一旦接口发生了变更就得重新写一下接口路径,这很麻烦,于是编写自定义注解完成这个繁琐的操作

正片开始
思路:自定义注解@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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值