
ruoyi框架源码阅读之--Anonymous注解 允许 匿名访问不鉴权
这个值得一看,好像还可以拿到其他项目直接用/*** 匿名访问不鉴权注解说不定会用的到,记录一下。
·
Anonymous注解 允许 匿名访问不鉴权
前言
这个值得一看,好像还可以拿到其他项目直接用
一、Anonymous定义
package com.ruoyi.common.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 匿名访问不鉴权注解
*
* @author ruoyi
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Anonymous {
}
二、注解配置
package com.ruoyi.framework.config.properties;
import java.util.*;
import java.util.regex.Pattern;
import org.apache.commons.lang3.RegExUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import com.ruoyi.common.annotation.Anonymous;
/**
* 设置Anonymous注解 允许 匿名访问不鉴权
* 项目初始化时候,会将Anonymous注解的 路径 提取出来,放到urls里面
*
* InitializingBean:为bean提供了初始化方法的方式,凡是继承该接口的类,在初始化bean的时候都会执行afterPropertiesSet方法
*
* ApplicationContextAware:当一个类实现了这个接口之后,这个类就可以方便的获得ApplicationContext对象(spring上下文)
* ,Spring发现某个Bean实现了ApplicationContextAware接口,Spring容器会在创建该Bean之后,自动调用该Bean的setApplicationContext(参数)方法
* ,调用该方法时,会将容器本身ApplicationContext对象作为参数传递给该方法。
*
* @author ruoyi
*/
@Configuration
public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware {
private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
// spring上下文
private ApplicationContext applicationContext;
// 前端请求接口的时候,如果在这个url里面,直接放行
private List<String> urls = new ArrayList<>();
// 替代字符串
public String ASTERISK = "*";
@Override
public void afterPropertiesSet() {
// 将整个项目所有bean都拿出来
RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
// 获取 每个url 与 方法、类的对应关系
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
// info 是代表每个url对象
map.keySet().forEach(info -> {
// 获取类和方法的信息
HandlerMethod handlerMethod = map.get(info);
// 获取方法上边的注解,如果此方法被“Anonymous”注解,则返回该方法,否则返回null
Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
// method为null啥也不干,否则替代path variable 为 *
Optional.ofNullable(method).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns())
.forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
// 获取类上边的注解,如果此类被“Anonymous”注解,则返回该类,否则返回null
Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);
// controller为null啥也不干,否则替代path variable 为 *
Optional.ofNullable(controller).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns())
.forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
});
}
/**
* @Description // 这玩意是接口ApplicationContextAware带来的,就是为了在本类中方便获取 applicationContext
* @Date 16:15 2023/3/22
**/
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.applicationContext = context;
}
public List<String> getUrls() {
return urls;
}
public void setUrls(List<String> urls) {
this.urls = urls;
}
}
三、Debug讲解
1、看看根据上下文获取到的是个啥,这个是获取到所有接口的 【访问路径:接口地址路径】
2、遍历获取每个路径的方法
3、判断当前方法有没有Anonymous注解哇
4、被Anonymous注解修饰的,将根据正则替换 链接字符串
5、最后 Security配置类中把 urls 中的访问地址给全部放行
总结
说不定会用的到,记录一下
更多推荐
所有评论(0)