如何在GET请求中识别地址内的参数是什么? request.getParameterMap()始终返回null

时间:2019-01-28 16:02:18

标签: java spring spring-security

我正在使用 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;
    }

// ...

}

1 个答案:

答案 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首先对路径进行解码的原因。