格式化代码,修改'{'对齐方式
This commit is contained in:
parent
e36b3642da
commit
a5d5787735
|
|
@ -19,16 +19,17 @@ import java.util.*;
|
||||||
/**
|
/**
|
||||||
* =====================================网关鉴权使用说明=======================================
|
* =====================================网关鉴权使用说明=======================================
|
||||||
* 场景:
|
* 场景:
|
||||||
* 微服务部署在内网,确定安全,无需在每个微服务都实现鉴权的逻辑,可以在网关层面实现统一鉴权
|
* 微服务部署在内网,确定安全,无需在每个微服务都实现鉴权的逻辑,可以在网关层面实现统一鉴权
|
||||||
* 使用方式:
|
* 使用方式:
|
||||||
* 1、在每个微服务的配置文件中添加参数:security.annotation.enabled: false 关闭系统默认的通过注解方式鉴权,默认开启
|
* 1、在每个微服务的配置文件中添加参数:security.annotation.enabled: false 关闭系统默认的通过注解方式鉴权,默认开启
|
||||||
* 2、在每个微服务的配置文件中添加参数:pathPrefix: 值为网关中微服务匹配的路由地址前缀,例如: /auth
|
* 2、在每个微服务的配置文件中添加参数:pathPrefix: 值为网关中微服务匹配的路由地址前缀,例如: /auth
|
||||||
* 3、在网关配置文件中添加参数:security.gateway.enabled: true 启用网关统一鉴权,默认关闭
|
* 3、在网关配置文件中添加参数:security.gateway.enabled: true 启用网关统一鉴权,默认关闭
|
||||||
*
|
* <p>
|
||||||
* 通过反射扫描所有控制器,缓存所有控制器的映射路径以及对应的权限注解,缓存到redis,方便网关鉴权
|
* 通过反射扫描所有控制器,缓存所有控制器的映射路径以及对应的权限注解,缓存到redis,方便网关鉴权
|
||||||
*/
|
*/
|
||||||
@ConditionalOnProperty(prefix = "security.annotation", name = "enabled", havingValue = "false")
|
@ConditionalOnProperty(prefix = "security.annotation", name = "enabled", havingValue = "false")
|
||||||
public class PathPermissionMappingConfig {
|
public class PathPermissionMappingConfig
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* 微服务在网关配置中predicates中的Path前缀,例如: /system
|
* 微服务在网关配置中predicates中的Path前缀,例如: /system
|
||||||
*/
|
*/
|
||||||
|
|
@ -36,7 +37,8 @@ public class PathPermissionMappingConfig {
|
||||||
private String pathPrefix;
|
private String pathPrefix;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public PathPermissionMappingConfig execute() {
|
public PathPermissionMappingConfig execute()
|
||||||
|
{
|
||||||
RedisService redisService = SpringUtils.getBean(RedisService.class);
|
RedisService redisService = SpringUtils.getBean(RedisService.class);
|
||||||
RequestMappingHandlerMapping bean = SpringUtils.getBean("requestMappingHandlerMapping");
|
RequestMappingHandlerMapping bean = SpringUtils.getBean("requestMappingHandlerMapping");
|
||||||
Map<RequestMappingInfo, HandlerMethod> handlerMethods = bean.getHandlerMethods();
|
Map<RequestMappingInfo, HandlerMethod> handlerMethods = bean.getHandlerMethods();
|
||||||
|
|
@ -45,7 +47,8 @@ public class PathPermissionMappingConfig {
|
||||||
*/
|
*/
|
||||||
Map<String, String> pathPermsMap = new TreeMap<>();
|
Map<String, String> pathPermsMap = new TreeMap<>();
|
||||||
|
|
||||||
handlerMethods.forEach((k, v) -> {
|
handlerMethods.forEach((k, v) ->
|
||||||
|
{
|
||||||
RequiresRoles requiresRoles = v.getMethodAnnotation(RequiresRoles.class);
|
RequiresRoles requiresRoles = v.getMethodAnnotation(RequiresRoles.class);
|
||||||
RequiresPermissions requiresPermissions = v.getMethodAnnotation(RequiresPermissions.class);
|
RequiresPermissions requiresPermissions = v.getMethodAnnotation(RequiresPermissions.class);
|
||||||
|
|
||||||
|
|
@ -54,21 +57,27 @@ public class PathPermissionMappingConfig {
|
||||||
/**
|
/**
|
||||||
* @RequestMapping注解
|
* @RequestMapping注解
|
||||||
*/
|
*/
|
||||||
if(methods.isEmpty()) {
|
if (methods.isEmpty())
|
||||||
|
{
|
||||||
methods = new HashSet<>();
|
methods = new HashSet<>();
|
||||||
methods.addAll(Arrays.asList(RequestMethod.GET, RequestMethod.POST));
|
methods.addAll(Arrays.asList(RequestMethod.GET, RequestMethod.POST));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(requiresPermissions == null && requiresRoles == null) {
|
if (requiresPermissions == null && requiresRoles == null)
|
||||||
|
{
|
||||||
addPathPermsMap(SecurityConstants.ROLE_ANON, pathPermsMap, methods, patternValues);
|
addPathPermsMap(SecurityConstants.ROLE_ANON, pathPermsMap, methods, patternValues);
|
||||||
}
|
}
|
||||||
if(requiresPermissions != null) {
|
if (requiresPermissions != null)
|
||||||
for (String perms : requiresPermissions.value()) {
|
{
|
||||||
|
for (String perms : requiresPermissions.value())
|
||||||
|
{
|
||||||
addPathPermsMap(perms, pathPermsMap, methods, patternValues);
|
addPathPermsMap(perms, pathPermsMap, methods, patternValues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(requiresRoles != null) {
|
if (requiresRoles != null)
|
||||||
for (String role : requiresRoles.value()) {
|
{
|
||||||
|
for (String role : requiresRoles.value())
|
||||||
|
{
|
||||||
addPathPermsMap(SecurityConstants.ROLE_PREFIX + role, pathPermsMap, methods, patternValues);
|
addPathPermsMap(SecurityConstants.ROLE_PREFIX + role, pathPermsMap, methods, patternValues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -80,14 +89,18 @@ public class PathPermissionMappingConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一个path对应多个perms
|
* 一个path对应多个perms
|
||||||
|
*
|
||||||
* @param perms
|
* @param perms
|
||||||
* @param pathPermsMap
|
* @param pathPermsMap
|
||||||
* @param methods
|
* @param methods
|
||||||
* @param patternValues
|
* @param patternValues
|
||||||
*/
|
*/
|
||||||
private void addPathPermsMap(String perms, Map<String, String> pathPermsMap, Set<RequestMethod> methods, Set<String> patternValues) {
|
private void addPathPermsMap(String perms, Map<String, String> pathPermsMap, Set<RequestMethod> methods, Set<String> patternValues)
|
||||||
for (RequestMethod method : methods) {
|
{
|
||||||
for (String patternValue : patternValues) {
|
for (RequestMethod method : methods)
|
||||||
|
{
|
||||||
|
for (String patternValue : patternValues)
|
||||||
|
{
|
||||||
String key = pathPrefix + patternValue + "_" + method.name();
|
String key = pathPrefix + patternValue + "_" + method.name();
|
||||||
pathPermsMap.put(key, perms);
|
pathPermsMap.put(key, perms);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网关鉴权
|
* 网关鉴权
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
|
@ -92,14 +92,17 @@ public class AuthFilter implements GlobalFilter, Ordered
|
||||||
// 内部请求来源参数清除
|
// 内部请求来源参数清除
|
||||||
removeHeader(mutate, SecurityConstants.FROM_SOURCE);
|
removeHeader(mutate, SecurityConstants.FROM_SOURCE);
|
||||||
// 通过网关鉴权
|
// 通过网关鉴权
|
||||||
if(gatewayAuth) {
|
if (gatewayAuth)
|
||||||
|
{
|
||||||
// admin不需要鉴权
|
// admin不需要鉴权
|
||||||
if(isAdmin(userid)) {
|
if (isAdmin(userid))
|
||||||
|
{
|
||||||
return chain.filter(exchange.mutate().request(mutate.build()).build());
|
return chain.filter(exchange.mutate().request(mutate.build()).build());
|
||||||
}
|
}
|
||||||
// 网关验证权限
|
// 网关验证权限
|
||||||
String api = url + "_" + request.getMethod().name();
|
String api = url + "_" + request.getMethod().name();
|
||||||
if(!hasPermission(api, userkey)) {
|
if (!hasPermission(api, userkey))
|
||||||
|
{
|
||||||
log.warn("无权访问:{}", api);
|
log.warn("无权访问:{}", api);
|
||||||
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "无权访问", HttpStatus.FORBIDDEN);
|
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "无权访问", HttpStatus.FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
@ -107,11 +110,13 @@ public class AuthFilter implements GlobalFilter, Ordered
|
||||||
return chain.filter(exchange.mutate().request(mutate.build()).build());
|
return chain.filter(exchange.mutate().request(mutate.build()).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAdmin(String userid) {
|
private boolean isAdmin(String userid)
|
||||||
|
{
|
||||||
return "1".equals(userid);
|
return "1".equals(userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasPermission(String api, String token) {
|
private boolean hasPermission(String api, String token)
|
||||||
|
{
|
||||||
// 使用JSONObject接收,避免导入依赖
|
// 使用JSONObject接收,避免导入依赖
|
||||||
JSONObject loginUser = redisService.getCacheObject(CacheConstants.LOGIN_TOKEN_KEY + token);
|
JSONObject loginUser = redisService.getCacheObject(CacheConstants.LOGIN_TOKEN_KEY + token);
|
||||||
// 获取登录用户的资源列表
|
// 获取登录用户的资源列表
|
||||||
|
|
@ -125,28 +130,33 @@ public class AuthFilter implements GlobalFilter, Ordered
|
||||||
.filter(entry -> match(entry.getKey(), api))
|
.filter(entry -> match(entry.getKey(), api))
|
||||||
.map(entry -> entry.getValue())
|
.map(entry -> entry.getValue())
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
if(!matchedPerms.isEmpty()) {
|
if (!matchedPerms.isEmpty())
|
||||||
|
{
|
||||||
// 所有角色权限
|
// 所有角色权限
|
||||||
Set<String> rolePerms = matchedPerms.stream().filter(item -> item.startsWith("ROLE_")).collect(Collectors.toSet());
|
Set<String> rolePerms = matchedPerms.stream().filter(item -> item.startsWith("ROLE_")).collect(Collectors.toSet());
|
||||||
// 所有资源权限
|
// 所有资源权限
|
||||||
matchedPerms.removeAll(rolePerms);
|
matchedPerms.removeAll(rolePerms);
|
||||||
|
|
||||||
if(!rolePerms.isEmpty()) {
|
if (!rolePerms.isEmpty())
|
||||||
if(rolePerms.contains(SecurityConstants.ROLE_ANON)) {
|
{
|
||||||
|
if (rolePerms.contains(SecurityConstants.ROLE_ANON))
|
||||||
|
{
|
||||||
log.debug("允许访问公共权限:{},{}", api, rolePerms);
|
log.debug("允许访问公共权限:{},{}", api, rolePerms);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
rolePerms = rolePerms.stream().map(item -> item.substring(SecurityConstants.ROLE_PREFIX.length())).collect(Collectors.toSet());
|
rolePerms = rolePerms.stream().map(item -> item.substring(SecurityConstants.ROLE_PREFIX.length())).collect(Collectors.toSet());
|
||||||
// 求交集
|
// 求交集
|
||||||
rolePerms.retainAll(roles);
|
rolePerms.retainAll(roles);
|
||||||
if(!rolePerms.isEmpty()) {
|
if (!rolePerms.isEmpty())
|
||||||
|
{
|
||||||
log.debug("允许访问角色权限:{}, {}", api, rolePerms);
|
log.debug("允许访问角色权限:{}, {}", api, rolePerms);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 求交集
|
// 求交集
|
||||||
matchedPerms.retainAll(permissions);
|
matchedPerms.retainAll(permissions);
|
||||||
if(!matchedPerms.isEmpty()) {
|
if (!matchedPerms.isEmpty())
|
||||||
|
{
|
||||||
log.debug("允许访问资源权限:{},{}", api, matchedPerms);
|
log.debug("允许访问资源权限:{},{}", api, matchedPerms);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -155,9 +165,11 @@ public class AuthFilter implements GlobalFilter, Ordered
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean match(String pattern, String api) {
|
private boolean match(String pattern, String api)
|
||||||
|
{
|
||||||
return antPathMatcher.match(pattern, api);
|
return antPathMatcher.match(pattern, api);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value)
|
private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value)
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue