提交 4c6e1e00 编写于 作者: H haoxr

refactor:添加资源服务器鉴权的注释说明

上级 abc9b901
......@@ -35,6 +35,9 @@ import java.util.List;
/**
* 资源服务器配置
*
* @author haoxr
* @date 2020-05-01
*/
@ConfigurationProperties(prefix = "security")
@AllArgsConstructor
......@@ -42,7 +45,7 @@ import java.util.List;
@EnableWebFluxSecurity
public class ResourceServerConfig {
private AuthorizationManager authorizationManager;
private ResourceServerManager resourceServerManager;
@Setter
private List<String> ignoreUrls;
......@@ -56,7 +59,7 @@ public class ResourceServerConfig {
http.oauth2ResourceServer().authenticationEntryPoint(authenticationEntryPoint());
http.authorizeExchange()
.pathMatchers(Convert.toStrArray(ignoreUrls)).permitAll()
.anyExchange().access(authorizationManager)
.anyExchange().access(resourceServerManager)
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler()) // 处理未授权
......
......@@ -17,6 +17,7 @@ import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -25,13 +26,14 @@ import static com.youlai.common.constant.AuthConstants.AUTHORITY_PREFIX;
/**
* 网关自定义鉴权管理器
* @author hxr
* @date 2021-06-07
*
* @author haoxr
* @date 2020-05-01
*/
@Component
@AllArgsConstructor
@Slf4j
public class AuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {
public class ResourceServerManager implements ReactiveAuthorizationManager<AuthorizationContext> {
private RedisTemplate redisTemplate;
......@@ -39,28 +41,33 @@ public class AuthorizationManager implements ReactiveAuthorizationManager<Author
public Mono<AuthorizationDecision> check(Mono<Authentication> mono, AuthorizationContext authorizationContext) {
ServerHttpRequest request = authorizationContext.getExchange().getRequest();
// Restful接口权限设计 @link https://www.cnblogs.com/haoxianrui/p/14396990.html
String restfulPath = request.getMethodValue() + "_" + request.getURI().getPath();
log.info("restful path:{}",restfulPath);
PathMatcher pathMatcher = new AntPathMatcher();
// 对应跨域的预检请求直接放行
// 预检请求放行
if (request.getMethod() == HttpMethod.OPTIONS) {
return Mono.just(new AuthorizationDecision(true));
}
// 从redis取【权限->角色(集合)】规则
// Restful接口权限设计 @link https://www.cnblogs.com/haoxianrui/p/14396990.html
String restfulPath = request.getMethodValue() + "_" + request.getURI().getPath();
log.info("请求方法 + RESTFul请求路径:{}", restfulPath);
// 缓存取【URL权限标识->角色集合】权限规则
Map<String, Object> permRolesRule = redisTemplate.opsForHash().entries(GlobalConstants.URL_PERM_ROLES_KEY);
Set<String> hasPermRoles = CollectionUtil.newHashSet(); // 有权限的角色集合
boolean needCheck = false; // 是否被设置需要鉴权
// 根据 “请求路径” 和 权限规则中的“URL权限标识”进行Ant匹配,得出拥有权限的角色集合
Set<String> hasPermissionRoles = CollectionUtil.newHashSet(); // 【声明定义】有权限的角色集合
boolean needToCheck = false; // 【声明定义】是否需要被拦截检查的请求,如果缓存中权限规则中没有任何URL权限标识和此次请求的URL匹配,默认不需要被鉴权
PathMatcher pathMatcher = new AntPathMatcher(); // 【声明定义】Ant路径匹配模式,“请求路径”和缓存中权限规则的“URL权限标识”匹配
for (Map.Entry<String, Object> permRoles : permRolesRule.entrySet()) {
String perm = permRoles.getKey(); // URL权限标识
String perm = permRoles.getKey(); // 缓存权限规则的键:URL权限标识
if (pathMatcher.match(perm, restfulPath)) {
List<String> roles = Convert.toList(String.class, permRoles.getValue());
hasPermRoles.addAll(Convert.toList(String.class, roles));
needCheck = true;
List<String> roles = Convert.toList(String.class, permRoles.getValue()); // 缓存权限规则的值:有请求路径访问权限的角色集合
hasPermissionRoles.addAll(Convert.toList(String.class, roles));
needToCheck = true;
}
}
// 如果没有设置权限拦截则放行
if (needCheck == false) {
if (needToCheck == false) {
return Mono.just(new AuthorizationDecision(true));
}
// 判断用户JWT中携带的角色是否有能通过权限拦截的角色
......@@ -69,12 +76,12 @@ public class AuthorizationManager implements ReactiveAuthorizationManager<Author
.flatMapIterable(Authentication::getAuthorities)
.map(GrantedAuthority::getAuthority)
.any(authority -> {
log.info("authority : {}", authority); // ROLE_ROOT
log.info("用户权限(角色) : {}", authority); // ROLE_ROOT
String role = authority.substring(AUTHORITY_PREFIX.length()); // ROOT
if (GlobalConstants.ROOT_ROLE_CODE.equals(role)) { // 如果是超级管理员则放行
return true;
}
return hasPermRoles.contains(role); // 用户角色中只要有一个满足则通过权限校验
return hasPermissionRoles.contains(role); // 用户角色中只要有一个满足则通过权限校验
})
.map(AuthorizationDecision::new)
.defaultIfEmpty(new AuthorizationDecision(false));
......
......@@ -24,11 +24,14 @@ import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 全局过滤器
* 安全拦截全局过滤器
*
* @author haoxr
* @date 2020-06-12
*/
@Component
@Slf4j
public class JwtGlobalFilter implements GlobalFilter, Ordered {
public class SecurityGlobalFilter implements GlobalFilter, Ordered {
@Autowired
private RedisTemplate redisTemplate;
......
......@@ -14,7 +14,7 @@ import reactor.core.publisher.Mono;
import java.nio.charset.Charset;
/**
* @Author haoxr
* @Author hxr
* @Date 2021-01-29 13:30
*/
public class ResponseUtils {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册