Как определить в запросах GET, что является параметром внутри адреса?request.getParameterMap () всегда возвращает ноль - PullRequest
0 голосов
/ 28 января 2019

Я реализую метод динамической проверки ролей для запросов в configure(HTTP HttpSecurity) с использованием класса реализации FilterInvocationSecurityMetadataSource , однако у меня возникают проблемы в методе 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 голосов
/ 28 января 2019

Контейнеры сервлетов не анализируют путь , они только обрабатывают строку запроса или application/x-www-form-urlencoded тело запроса.Из раздела 3.1 в Servlet Spec:

Данные из строки запроса и тела сообщения объединяются в набор параметров запроса.

Чтобы извлечь путь, вам нужно разобрать его самостоятельно, хотя 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");

Помните, что контейнеры сервлетов могут не декодировать путь, как они делают строку запроса, поэтому код выше использует UrlPathHelper для первого декодирования пути.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...