场景
项目中某些接口不需要认证, 通过注解实现相对于其他的security配置会更灵活。
解决方案
- 按照HTTP方法的维度 获取到uri集合
- 使用antMatchers(HttpMethod method, String… antPatterns) 完成搜集的uri配置
antMatchers(HttpMethod method, String… antPatterns) 是 Spring Security 中用于配置 特定 HTTP 方法和 URL 模式的安全规则。
HttpMethod method 表示要匹配的 HTTP 方法(例如 GET、POST、PUT 等)。
String… antPatterns 表示要匹配的 URL 模式,可以指定多个模式。 可以设置成ur数组
下面是个例子
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/public/**").permitAll() // 允许GET请求访问/public/**路径
.antMatchers(HttpMethod.POST, "/admin/**").hasRole("ADMIN") // 需要ADMIN角色才能POST访问/admin/**路径
.anyRequest().authenticated() // 其他请求需要进行身份验证
代码实现
- 获取PermitAll注解修饰的uri
/**
* 获取被PermitAll注解修饰的url地址
* */
private Multimap<RequestMethod, String> getUrlsFormPermitAllAnnotation() {
Multimap<RequestMethod, String> methodMap = HashMultimap.create();
RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : requestMappingHandlerMapping.getHandlerMethods().entrySet()) {
HandlerMethod method = entry.getValue();
if (!method.hasMethodAnnotation(PermitAll.class)) {
continue;
}
if (entry.getKey().getPatternsCondition() == null) {
continue;
}
Set<String> url = entry.getKey().getPatternsCondition().getPatterns();
for (RequestMethod requestMethod : entry.getKey().getMethodsCondition().getMethods()) {
methodMap.putAll(requestMethod, url);
}
}
log.info("PermitAll注解修饰的urls {}", methodMap);
return methodMap;
}
- 将uri设置成无需认证
Multimap<RequestMethod, String> permitAllUrlMap = getUrlsFormPermitAllAnnotation();
// 设置具体请求的权限
httpSecurity.authorizeRequests()
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() // 静态资源无需认证
.antMatchers("/websocket/message").permitAll() // websocket无需认证
.antMatchers(HttpMethod.GET, permitAllUrlMap.get(RequestMethod.GET).toArray(new String[0])).permitAll()
.antMatchers(HttpMethod.POST, permitAllUrlMap.get(RequestMethod.POST).toArray(new String[0])).permitAll()
.antMatchers(HttpMethod.PUT, permitAllUrlMap.get(RequestMethod.PUT).toArray(new String[0])).permitAll()
.antMatchers(HttpMethod.DELETE, permitAllUrlMap.get(RequestMethod.DELETE).toArray(new String[0])).permitAll()
.and().authorizeRequests().anyRequest().authenticated(); // 其他请求必须认证