初始化
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package com.njcn.gateway.security;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.njcn.redis.pojo.enums.RedisKeyEnum;
|
||||
import com.njcn.redis.utils.RedisUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.web.server.authorization.AuthorizationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* 鉴权管理器
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class AuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {
|
||||
|
||||
private final RedisUtil redisUtil;
|
||||
|
||||
@Override
|
||||
public Mono<AuthorizationDecision> check(Mono<Authentication> mono, AuthorizationContext authorizationContext) {
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
ServerHttpRequest request = authorizationContext.getExchange().getRequest();
|
||||
//不追究请求方式,如果需追求,需要在数据库中添加请求方式的字段request.getMethodValue()
|
||||
String restPath = request.getURI().getPath();
|
||||
log.info("请求路径:{}", restPath);
|
||||
// 对应跨域的预检请求直接放行
|
||||
// if (request.getMethod() == HttpMethod.OPTIONS) {
|
||||
// return Mono.just(new AuthorizationDecision(true));
|
||||
// }
|
||||
// 是否需要鉴权,默认未设置拦截规则需要鉴权
|
||||
boolean requireCheck = true;
|
||||
//查看是否为公共资源
|
||||
List<String> publicFunctions = (List<String>) redisUtil.getObjectByKey(RedisKeyEnum.PUBLIC_FUNCTIONS_KEY.getKey());
|
||||
if (CollectionUtil.isNotEmpty(publicFunctions) && publicFunctions.contains(restPath)) {
|
||||
requireCheck = false;
|
||||
}
|
||||
// 从缓存取资源权限角色关系列表
|
||||
Object roleFunctionsObject = redisUtil.getObjectByKey(RedisKeyEnum.ROLE_FUNCTION_KEY.getKey());
|
||||
if (!Objects.isNull(roleFunctionsObject)) {
|
||||
Map<String, List<String>> roleFunctions = (Map<String, List<String>>) roleFunctionsObject;
|
||||
//当前资源需要的角色
|
||||
Set<String> authorities = new HashSet<>();
|
||||
Set<String> roleNames = roleFunctions.keySet();
|
||||
roleNames.forEach(roleName -> {
|
||||
List<String> functionPaths = roleFunctions.get(roleName);
|
||||
if (CollectionUtil.isNotEmpty(functionPaths) && functionPaths.contains(restPath)) {
|
||||
authorities.add(roleName);
|
||||
}
|
||||
});
|
||||
boolean finalRequireCheck = requireCheck;
|
||||
return mono
|
||||
.filter(Authentication::isAuthenticated)
|
||||
.flatMapIterable(Authentication::getAuthorities)
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.any(roleId -> {
|
||||
if (!finalRequireCheck || roleId.equals("ROLE_root")) {
|
||||
return true;
|
||||
} else {
|
||||
return authorities.contains(roleId);
|
||||
}
|
||||
})
|
||||
.map(AuthorizationDecision::new)
|
||||
.defaultIfEmpty(new AuthorizationDecision(false));
|
||||
}
|
||||
return Mono.just(new AuthorizationDecision(true));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user