|
|
@@ -1,7 +1,11 @@ |
|
|
|
package com.xkcoding.rbac.security.config; |
|
|
|
|
|
|
|
import cn.hutool.core.util.StrUtil; |
|
|
|
import com.google.common.collect.ArrayListMultimap; |
|
|
|
import com.google.common.collect.Multimap; |
|
|
|
import com.xkcoding.rbac.security.common.Consts; |
|
|
|
import com.xkcoding.rbac.security.common.Status; |
|
|
|
import com.xkcoding.rbac.security.exception.SecurityException; |
|
|
|
import com.xkcoding.rbac.security.model.Permission; |
|
|
|
import com.xkcoding.rbac.security.model.Role; |
|
|
|
import com.xkcoding.rbac.security.repository.PermissionDao; |
|
|
@@ -12,10 +16,16 @@ import org.springframework.security.core.Authentication; |
|
|
|
import org.springframework.security.core.userdetails.UserDetails; |
|
|
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
import org.springframework.web.method.HandlerMethod; |
|
|
|
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition; |
|
|
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfo; |
|
|
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; |
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Objects; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
/** |
|
|
@@ -39,7 +49,12 @@ public class RbacAuthorityService { |
|
|
|
@Autowired |
|
|
|
private PermissionDao permissionDao; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private RequestMappingHandlerMapping mapping; |
|
|
|
|
|
|
|
public boolean hasPermission(HttpServletRequest request, Authentication authentication) { |
|
|
|
checkRequestNotFound(request); |
|
|
|
|
|
|
|
Object userInfo = authentication.getPrincipal(); |
|
|
|
boolean hasPermission = false; |
|
|
|
|
|
|
@@ -76,4 +91,60 @@ public class RbacAuthorityService { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 校验请求是否存在 |
|
|
|
* |
|
|
|
* @param request 请求 |
|
|
|
*/ |
|
|
|
private void checkRequestNotFound(HttpServletRequest request) { |
|
|
|
// 获取当前 request 的方法 |
|
|
|
String currentMethod = request.getMethod(); |
|
|
|
Multimap<String, String> urlMapping = allUrlMapping(); |
|
|
|
|
|
|
|
for (String uri : urlMapping.keySet()) { |
|
|
|
// 通过 AntPathRequestMatcher 匹配 url |
|
|
|
// 可以通过 2 种方式创建 AntPathRequestMatcher |
|
|
|
// 1:new AntPathRequestMatcher(uri,method) 这种方式可以直接判断方法是否匹配,因为这里我们把 方法不匹配 自定义抛出,所以,我们使用第2种方式创建 |
|
|
|
// 2:new AntPathRequestMatcher(uri) 这种方式不校验请求方法,只校验请求路径 |
|
|
|
AntPathRequestMatcher antPathMatcher = new AntPathRequestMatcher(uri); |
|
|
|
if (antPathMatcher.matches(request)) { |
|
|
|
if (!urlMapping.get(uri) |
|
|
|
.contains(currentMethod)) { |
|
|
|
throw new SecurityException(Status.HTTP_BAD_METHOD); |
|
|
|
} else { |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
throw new SecurityException(Status.REQUEST_NOT_FOUND); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 获取 所有URL Mapping,返回格式为{"/test":["GET","POST"],"/sys":["GET","DELETE"]} |
|
|
|
* |
|
|
|
* @return {@link ArrayListMultimap} 格式的 URL Mapping |
|
|
|
*/ |
|
|
|
private Multimap<String, String> allUrlMapping() { |
|
|
|
Multimap<String, String> urlMapping = ArrayListMultimap.create(); |
|
|
|
|
|
|
|
// 获取url与类和方法的对应信息 |
|
|
|
Map<RequestMappingInfo, HandlerMethod> handlerMethods = mapping.getHandlerMethods(); |
|
|
|
|
|
|
|
handlerMethods.forEach((k, v) -> { |
|
|
|
// 获取当前 key 下的获取所有URL |
|
|
|
Set<String> url = k.getPatternsCondition() |
|
|
|
.getPatterns(); |
|
|
|
RequestMethodsRequestCondition method = k.getMethodsCondition(); |
|
|
|
|
|
|
|
// 为每个URL添加所有的请求方法 |
|
|
|
url.forEach(s -> urlMapping.putAll(s, method.getMethods() |
|
|
|
.stream() |
|
|
|
.map(Enum::toString) |
|
|
|
.collect(Collectors.toList()))); |
|
|
|
}); |
|
|
|
|
|
|
|
return urlMapping; |
|
|
|
} |
|
|
|
} |