Browse Source

完善 404 异常和 405 异常

pull/1/head
Yangkai.Shen 6 years ago
parent
commit
b006e59b35
2 changed files with 78 additions and 4 deletions
  1. +71
    -0
      spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/config/RbacAuthorityService.java
  2. +7
    -4
      spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/controller/TestController.java

+ 71
- 0
spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/config/RbacAuthorityService.java View File

@@ -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;
}
}

+ 7
- 4
spring-boot-demo-rbac-security/src/main/java/com/xkcoding/rbac/security/controller/TestController.java View File

@@ -2,10 +2,7 @@ package com.xkcoding.rbac.security.controller;

import com.xkcoding.rbac.security.common.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

/**
* <p>
@@ -35,4 +32,10 @@ public class TestController {
log.info("测试列表添加");
return ApiResponse.ofMessage("测试列表添加");
}

@PutMapping("/{id}")
public ApiResponse update(@PathVariable Long id) {
log.info("测试列表修改");
return ApiResponse.ofSuccess("测试列表修改");
}
}

Loading…
Cancel
Save