mirror of https://github.com/elunez/eladmin
[代码完成](v2.5): 匿名接口SecurityConfig配置细腻化,支持不同类型的接口放行
parent
4ddf97ce9c
commit
38a8516ed7
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package me.zhengjie.utils.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Zheng Jie
|
||||||
|
* @website https://el-admin.vip
|
||||||
|
* @description
|
||||||
|
* @date 2020-06-10
|
||||||
|
**/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum RequestMethodEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜寻 @AnonymousGetMapping
|
||||||
|
*/
|
||||||
|
GET("GET"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜寻 @AnonymousPostMapping
|
||||||
|
*/
|
||||||
|
POST("POST"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜寻 @AnonymousPutMapping
|
||||||
|
*/
|
||||||
|
PUT("PUT"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜寻 @AnonymousPatchMapping
|
||||||
|
*/
|
||||||
|
PATCH("PATCH"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜寻 @AnonymousDeleteMapping
|
||||||
|
*/
|
||||||
|
DELETE("DELETE"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 否则就是所有 Request 接口都放行
|
||||||
|
*/
|
||||||
|
ALL("All");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request 类型
|
||||||
|
*/
|
||||||
|
private final String type;
|
||||||
|
|
||||||
|
public static RequestMethodEnum find(String type) {
|
||||||
|
for (RequestMethodEnum value : RequestMethodEnum.values()) {
|
||||||
|
if (type.equals(value.getType())) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ALL;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ package me.zhengjie.modules.security.config;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import me.zhengjie.annotation.AnonymousAccess;
|
import me.zhengjie.annotation.AnonymousAccess;
|
||||||
import me.zhengjie.modules.security.security.*;
|
import me.zhengjie.modules.security.security.*;
|
||||||
|
import me.zhengjie.utils.enums.RequestMethodEnum;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -31,13 +32,12 @@ import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.filter.CorsFilter;
|
import org.springframework.web.filter.CorsFilter;
|
||||||
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.method.HandlerMethod;
|
||||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Zheng Jie
|
* @author Zheng Jie
|
||||||
|
@ -70,14 +70,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
protected void configure(HttpSecurity httpSecurity) throws Exception {
|
protected void configure(HttpSecurity httpSecurity) throws Exception {
|
||||||
// 搜寻匿名标记 url: @AnonymousAccess
|
// 搜寻匿名标记 url: @AnonymousAccess
|
||||||
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();
|
Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();
|
||||||
Set<String> anonymousUrls = new HashSet<>();
|
// 获取匿名标记
|
||||||
for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {
|
Map<String, Set<String>> anonymousUrls = getAnonymousUrl(handlerMethodMap);
|
||||||
HandlerMethod handlerMethod = infoEntry.getValue();
|
|
||||||
AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
|
|
||||||
if (null != anonymousAccess) {
|
|
||||||
anonymousUrls.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
httpSecurity
|
httpSecurity
|
||||||
// 禁用 CSRF
|
// 禁用 CSRF
|
||||||
.csrf().disable()
|
.csrf().disable()
|
||||||
|
@ -86,18 +80,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
.exceptionHandling()
|
.exceptionHandling()
|
||||||
.authenticationEntryPoint(authenticationErrorHandler)
|
.authenticationEntryPoint(authenticationErrorHandler)
|
||||||
.accessDeniedHandler(jwtAccessDeniedHandler)
|
.accessDeniedHandler(jwtAccessDeniedHandler)
|
||||||
|
|
||||||
// 防止iframe 造成跨域
|
// 防止iframe 造成跨域
|
||||||
.and()
|
.and()
|
||||||
.headers()
|
.headers()
|
||||||
.frameOptions()
|
.frameOptions()
|
||||||
.disable()
|
.disable()
|
||||||
|
|
||||||
// 不创建会话
|
// 不创建会话
|
||||||
.and()
|
.and()
|
||||||
.sessionManagement()
|
.sessionManagement()
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||||
|
|
||||||
.and()
|
.and()
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
// 静态资源等等
|
// 静态资源等等
|
||||||
|
@ -121,13 +112,69 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
.antMatchers("/druid/**").permitAll()
|
.antMatchers("/druid/**").permitAll()
|
||||||
// 放行OPTIONS请求
|
// 放行OPTIONS请求
|
||||||
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
||||||
// 自定义匿名访问所有url放行 : 允许匿名和带权限以及登录用户访问
|
// 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型
|
||||||
.antMatchers(anonymousUrls.toArray(new String[0])).permitAll()
|
// GET
|
||||||
|
.antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll()
|
||||||
|
// POST
|
||||||
|
.antMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll()
|
||||||
|
// PUT
|
||||||
|
.antMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll()
|
||||||
|
// PATCH
|
||||||
|
.antMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll()
|
||||||
|
// DELETE
|
||||||
|
.antMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll()
|
||||||
|
// 所有类型的接口都放行
|
||||||
|
.antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll()
|
||||||
// 所有请求都需要认证
|
// 所有请求都需要认证
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
.and().apply(securityConfigurerAdapter());
|
.and().apply(securityConfigurerAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, Set<String>> getAnonymousUrl(Map<RequestMappingInfo, HandlerMethod> handlerMethodMap) {
|
||||||
|
Map<String, Set<String>> anonymousUrls = new HashMap<>();
|
||||||
|
Set<String> get = new HashSet<>();
|
||||||
|
Set<String> post = new HashSet<>();
|
||||||
|
Set<String> put = new HashSet<>();
|
||||||
|
Set<String> patch = new HashSet<>();
|
||||||
|
Set<String> delete = new HashSet<>();
|
||||||
|
Set<String> all = new HashSet<>();
|
||||||
|
for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {
|
||||||
|
HandlerMethod handlerMethod = infoEntry.getValue();
|
||||||
|
AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
|
||||||
|
if (null != anonymousAccess) {
|
||||||
|
List<RequestMethod> requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods());
|
||||||
|
RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name());
|
||||||
|
switch (Objects.requireNonNull(request)){
|
||||||
|
case GET:
|
||||||
|
get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
||||||
|
break;
|
||||||
|
case POST:
|
||||||
|
post.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
||||||
|
break;
|
||||||
|
case PUT:
|
||||||
|
put.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
||||||
|
break;
|
||||||
|
case PATCH:
|
||||||
|
patch.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
||||||
|
break;
|
||||||
|
case DELETE:
|
||||||
|
delete.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
all.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
anonymousUrls.put(RequestMethodEnum.GET.getType(), get);
|
||||||
|
anonymousUrls.put(RequestMethodEnum.POST.getType(), post);
|
||||||
|
anonymousUrls.put(RequestMethodEnum.PUT.getType(), put);
|
||||||
|
anonymousUrls.put(RequestMethodEnum.PATCH.getType(), patch);
|
||||||
|
anonymousUrls.put(RequestMethodEnum.DELETE.getType(), delete);
|
||||||
|
anonymousUrls.put(RequestMethodEnum.ALL.getType(), all);
|
||||||
|
return anonymousUrls;
|
||||||
|
}
|
||||||
|
|
||||||
private TokenConfigurer securityConfigurerAdapter() {
|
private TokenConfigurer securityConfigurerAdapter() {
|
||||||
return new TokenConfigurer(tokenProvider);
|
return new TokenConfigurer(tokenProvider);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue