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;
}
}