导包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
注解
package com.zhk.study.annotation;
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 AnonymousAccess {
}
配置类
package com.zhk.study.config;
import com.zhk.study.annotation.AnonymousAccess;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.pattern.PathPattern;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)//开启注解支持
public class SecurityConfig{
@Autowired
private ApplicationContext applicationContext;
@Bean
@SneakyThrows
public SecurityFilterChain filterChain(HttpSecurity http) {
http.formLogin()//开启表单认证
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.and()
.authorizeRequests()
//匿名访问的路径
.antMatchers(getAnonymousUrls())
.anonymous()
.anyRequest()
.authenticated();
return http.build();
}
/**
* 获取标有注解 AnonymousAccess 的访问路径
*/
private String[] getAnonymousUrls() {
// 获取所有的 RequestMapping
Map<RequestMappingInfo, HandlerMethod> handlerMethods = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();
Set<String> allAnonymousAccess = new HashSet<>();
// 循环 RequestMapping
for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethods.entrySet()) {
HandlerMethod value = infoEntry.getValue();
// 获取方法上 AnonymousAccess 类型的注解
AnonymousAccess methodAnnotation = value.getMethodAnnotation(AnonymousAccess.class);
// 如果方法上标注了 AnonymousAccess 注解,就获取该方法的访问全路径
if (methodAnnotation != null) {
Set<String> collect = infoEntry
.getKey()
.getPathPatternsCondition()
.getPatterns()
.stream()
.map(PathPattern::getPatternString)
.collect(Collectors.toSet());
allAnonymousAccess.addAll(collect);
}
}
return allAnonymousAccess.toArray(new String[0]);
}
}
使用
@RestController
public class TestController {
@AnonymousAccess
@RequestMapping("/test")
public String test() {
return "success";
}
}