我正在使用 FilterInvocationSecurityMetadataSource 实现类实现一种动态验证configure(HTTP HttpSecurity)
中请求角色的方法,但是,我在getAttributes(Object object)
方法中遇到问题以识别GET请求中地址内的参数是什么。
例如,当/api/users/user.name请求到达时,此请求的方法为@GetMapping("/users/{login: "+ Constants.LOGIN_REGEX +"}")
,正如我知道的那样,对于此请求,字符串user.name
是基于URI的值在@GetMapping中设置什么?
我尝试使用request.getParameterMap()
,但它总是为空。
到目前为止我所做的:
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends ResourceServerConfigurerAdapter {
// ....
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.addFilterBefore(corsFilter, CsrfFilter.class)
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.anyRequest().authenticated()
.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
public <O extends FilterSecurityInterceptor> O postProcess(
O fsi) {
fsi.setSecurityMetadataSource(dynamicSecurityMetadataSource);
fsi.setAccessDecisionManager(new SecurityAccessDecisionManager());
return fsi;
}
});
}
// ...
}
实施FilterInvocationSecurityMetadataSource:
@Component
public class DynamicSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
@Autowired
private SystemURLRepository systemURLRepository;
@Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
final HttpServletRequest request = ((FilterInvocation) object).getRequest();
// Get request method (post, get, delete, ...)
String requestMethod = request.getMethod();
// Get string url from request
String urlWithoutContextPath = request.getRequestURI().substring(request.getContextPath().length());
// Query to verify roles from URI`s
Optional<SystemURL> foundUrl = systemURLRepository.findAllByValue(urlWithoutContextPath);
// If exists in database, return Collection contains information Roles
if(foundUrl.isPresent()){
Collection<ConfigAttribute> rolesAllowed = foundUrl.get().getRolesAllowed().stream().map(this::configAttribute).collect(Collectors.toList());
return rolesAllowed;
}
return null;
}
// ...
}
答案 0 :(得分:1)
Servlet容器don't parse the path,它们仅处理查询字符串或application/x-www-form-urlencoded
请求主体。从Servlet规范的第3.1节开始:
来自查询字符串和帖子正文的数据汇总到请求中 参数集。
要提取路径,您需要自己解析,尽管spring-web
确实为它提供了一些支持,如果您对此情况感兴趣的话:
AntPathMatcher matcher = new AntPathMatcher();
UrlPathHelper helper = new UrlPathHelper();
Map<String, String> extracted =
matcher.extractUriTemplateVariables("/user/{userName}",
helper.getLookupPathForRequest(request));
String userName = extracted.get("userName");
请记住,Servlet容器可能不会像查询字符串一样对路径进行解码,这就是为什么上面的代码使用UrlPathHelper
首先对路径进行解码的原因。