Безопасность Spring: невозможно добавить доступ к ресурсу при добавлении пользовательского фильтра - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть следующая конфигурация для моей весенней безопасности

http
    // if I gonna comment adding filter it's gonna work as expected
    .addFilterBefore(tokenAuthenticationFilter, BasicAuthenticationFilter.class)
            .authorizeRequests()
            .antMatchers("/rest/_health")
            .permitAll()

            .anyRequest()
            .authenticated()

            .and()
            .csrf()
            .disable();

Так что без пользовательского фильтра все работает как положено - у меня есть доступ к / rest / _health и доступ запрещен ко всему остальному.

Но когда я добавляю этот фильтр - сопоставители не работают, и фильтр работает даже для ресурсов allowAll.

Код из моего фильтра выглядит так:

@Override
public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    try {
        String token = httpRequest.getHeader(HttpHeaders.AUTHORIZATION);

        Authentication authentication = authenticationManager.authenticate(
                new TokenBasedAuthentication(token)
        );

        SecurityContextHolder.getContext().setAuthentication(authentication);

        chain.doFilter(request, response);
    } catch (AuthenticationException ex) {
        authenticationEntryPoint.commence(httpRequest, httpResponse, ex);
    }
}

Есть предложения?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Фильтр выполняется перед проверками на конечных точках. В вашем случае неудачная аутентификация прерывает цепочку фильтров и позволяет точке доступа обрабатывать все остальное. При этом вы вообще не разрешаете анонимный доступ. Необходимо установить для параметра Аутентификация значение null, чтобы указать, что анонимный пользователь обращается к конечной точке.

Попробуйте следующее:

    Authentication authentication = null;
    String token = httpRequest.getHeader(HttpHeaders.AUTHORIZATION);
    //check if not anonymous and preceed with authentication
    if (token != null && !token.isEmpty()) {
        try {

            authentication = authenticationManager.authenticate(
                new TokenBasedAuthentication(token));

        } catch (AuthenticationException ex) {
            //illigal access atempt
            authenticationEntryPoint.commence(httpRequest, httpResponse, ex);
        }
    }
    SecurityContextHolder.getContext().setAuthentication(authentication);
    chain.doFilter(request, response);
0 голосов
/ 05 сентября 2018

В моей конфигурации (которая расширяет WebSecurityConfigurerAdapter) я сделал это следующим образом:

        http.csrf().disable().
            addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
            .antMatchers("/login*", "/logout*").permitAll().anyRequest()
            .authenticated()
        .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/secured/index")
                .failureUrl("/login?error=true").permitAll()
        .and()
            .logout()
                .invalidateHttpSession(true)
                .clearAuthentication(true)
                .deleteCookies("JSESSIONID")
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login")
                .permitAll();

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/static/**", "/webjars/**", "/error*");
}

Возможно, не идеально, но это работает.

...