简体   繁体   English

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

[英]How to identify in the GET requests what is parameter inside the address? request.getParameterMap() always returns null

I'm implementing a method for dynamic validation of roles for requests in configure(HTTP HttpSecurity) using a FilterInvocationSecurityMetadataSource implementation class, however, I'm having problems in the getAttributes(Object object) method to identify in the GET requests what is parameter inside the address.我正在使用FilterInvocationSecurityMetadataSource实现类实现一种对configure(HTTP HttpSecurity)请求的角色进行动态验证的方法,但是,我在getAttributes(Object object)方法中遇到了问题,无法在 GET 请求中识别内部参数地址。 For example, when the /api/users/user.name request arrives the method for this request is @GetMapping("/users/{login: "+ Constants.LOGIN_REGEX +"}") , as I do to know that for this request the string user.name is a value in the URI based on what is set in @GetMapping?例如,当 /api/users/user.name 请求到达时,此请求的方法是@GetMapping("/users/{login: "+ Constants.LOGIN_REGEX +"}") ,因为我知道这一点请求字符串user.name是基于 @GetMapping 中设置的 URI 中的值?

I tried with request.getParameterMap() but it always gets null.我试过request.getParameterMap()但它总是为空。

What I've done so far:到目前为止我所做的:

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

// ...
}

Implementation FilterInvocationSecurityMetadataSource:实现 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;
    }

// ...

}

Servlet Containers don't parse the path , they only process the query string or an application/x-www-form-urlencoded request body. Servlet 容器不解析路径,它们只处理查询字符串或application/x-www-form-urlencoded请求正文。 From section 3.1 in the Servlet Spec:来自 Servlet 规范的第 3.1 节:

Data from the query string and the post body are aggregated into the request parameter set.来自查询字符串和帖子正文的数据聚合到请求参数集中。

To extract the path, you'll need to parse it yourself, though spring-web does provide some support for it, if that is of interest in your situation:要提取路径,您需要自己解析它,尽管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");

Remember that Servlet Containers may not decode the path like they do the query string, which is why the code above uses UrlPathHelper to first decode the path.请记住,Servlet 容器可能不会像对查询字符串那样解码路径,这就是为什么上面的代码使用UrlPathHelper来首先解码路径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM