WebSecurityConfigurerAdapter игнорирует AuthenticationFilter, но все равно отправляет 403 - PullRequest
0 голосов
/ 23 сентября 2019

Я, ради бога, не могу понять, что не так с моим WebSecurityConfigurerAdapter в моем приложении для весенней загрузки.

Я пишу собственный фильтр авторизации, чтобы получить некоторые пользовательские роли, специфичные для нашего приложения.

Я добавил Spring API в мой API и согласно требованию проигнорировал определенный набор URL (начиная с abc здесь).Моя конфигурация выглядит следующим образом

@Configuration
@EnableWebSecurity
public class AuthenticationConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(AuthenticationManagerBuilder builder) {
        builder.authenticationProvider(tokenAuthenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/abc/**").permitAll()
                .antMatchers("/**").fullyAuthenticated()
                .and()
                .addFilterBefore(new AuthenticationFilter(authenticationManager()), BasicAuthenticationFilter.class)
                .authenticationProvider(tokenAuthenticationProvider());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/abc/**");

    @Bean
    public AuthenticationProvider tokenAuthenticationProvider() {
        return new TokenAuthenticationProvider();
    }
}

У меня были некоторые проблемы при написании этой конфигурации и ее настройке, но она работала нормально;пока другой разработчик не добавил новый API, который также начинается с abc.

Новый URL с abc не соответствует моему AuthenticationFilter НО он отправляет 403 всегда, что бы ни случилось.Я пробовал по крайней мере 50 конфигураций, но это не делает этот новый фильтр аутентификации URL вообще.Старый URL (с abc), который я настроил ранее, работает нормально.Другой URL, который должен иметь аутентификацию, также работает должным образом.

Очевидно, что у меня есть последнее средство проверки URL в моем AuthFilter, но я не хочу делать это вручную, когда Spring предоставляет эти возможности из коробки..

Мой фильтр аутентификации:

public class AuthenticationFilter extends OncePerRequestFilter
{

    private AuthenticationManager authenticationManager;

    public AuthenticationFilter(AuthenticationManager authenticationManager)
    {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException
    {

        try
        {
            Context authContext = new Context();
            authContext.setProperty(AuthHeaders.HEADER_AUTHORIZATION, request.getHeader(AuthHeaders.HEADER_AUTHORIZATION));
            authContext.setProperty(AuthHeaders.HEADER_TOKEN_VERIFIED, request.getHeader(AuthHeaders.HEADER_TOKEN_VERIFIED));

            // Authenticate
            authenticate(authContext);

            filterChain.doFilter(request, response);
        }
        catch (InternalAuthenticationServiceException internalAuthenticationServiceException)
        {
            SecurityContextHolder.clearContext();
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
        catch (AuthenticationException authenticationException)
        {
            SecurityContextHolder.clearContext();
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
        }
    }

    private void authenticate(Context authContext)
    {
        PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(authContext, null);
        SecurityContextHolder.getContext().setAuthentication(authenticate(requestAuthentication));
    }

    private Authentication authenticate(Authentication authentication)
    {
        Authentication auth = authenticationManager.authenticate(authentication);
        if (auth == null)
        {
            throw new InternalAuthenticationServiceException("Could not authenticate");
        }
        if (!auth.isAuthenticated())
        {
            throw new BadCredentialsException("Token is not authenticated");
        }
        return auth;
    }
}

Мой провайдер аутентификации:


public class TokenAuthenticationProvider implements AuthenticationProvider {
    public TokenAuthenticationProvider() 
    {}

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Context authContext = (Context) authentication.getPrincipal();
        if (authContext == null) {
            authentication.setAuthenticated(false);
            throw new BadCredentialsException("Invalid Authentication header/context");
        }

        // setting authenticated to true for the sake of explanation
        authentication.setAuthenticated(true);
        return authentication;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(PreAuthenticatedAuthenticationToken.class);
    }
}
...