Home > front end >  Why antMatchers not working and trying to authenticate Login route?
Why antMatchers not working and trying to authenticate Login route?

Time:01-23

I am having trouble making authentication API in spring security.

I have the setup for the JWT login and register routes with Spring Security OncePerRequestFilter. For some reason, When I try to login myself in, it also tries to run doFilter method. Meaning, even though the user is trying to login with username and password, my api looks for jwt Bearer token.

I have my SecurityConfig.java as follows but the antMatchers do not work for login path as I thought.

Can someone help me please?

SecurityConfig.java

@Configuration
@AllArgsConstructor
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final AppUserService appUserService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private JwtFilter jwtFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable();

        http
                .authorizeRequests()
                .antMatchers("/api-docs", "/swagger").permitAll()
                .antMatchers("/api/v0/auth/login").permitAll()
                .antMatchers("/h2-console/**").permitAll()
                .anyRequest()
                .authenticated();

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(this.jwtFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(this.daoAuthenticationProvider());
    }

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(this.bCryptPasswordEncoder);
        provider.setUserDetailsService(this.appUserService);
        return provider;
    }
}
@RestController
@AllArgsConstructor
@RequestMapping(path = "/api/v0/auth")
public class AuthController {

    @Autowired
    private AuthService authService;

    @PostMapping("/login")
    public ResponseEntity<AuthResponse> login(@RequestBody LoginRequest request) throws Exception {
        AuthResponse response = this.authService.login(request);
        return ResponseEntity.ok().body(response);
    }
// ..... the rest

When I access /api-docs", "/swagger", the API does not try to authenticate. But the API does for /api/v0/auth/login, because I can see the log I added in doFilter in the log after sending request to /api/v0/auth/login

@Component
public class JwtFilter extends OncePerRequestFilter {

    private Logger log = LoggerFactory.getLogger(JwtFilter.class);

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


        String authorization = request.getHeader("Authorization");
        String token = null;
        String userName = null;
        log.info("@@ doFilterInternal: {}", authorization);
        
        // jwt and authentication stuff

        filterChain.doFilter(request, response);
    }
}

// what I see in the log for login request
// 2023-01-22 09:49:06.716  INFO 15780 --- [nio-8080-exec-1] c.h.s.config.security.filter.JwtFilter   : @@ doFilterInternal: null

Since I added a login endpoint in antMatchers, it should not log this and skip the authentication I believe. Can someone help me with what I am missing?

CodePudding user response:

See this post, with a HttpSecurity config for permitAll you are not bypassing filters -> Spring Security with filters permitAll not working. If you do not want to have your filter be called, you can move that url exclude config to WebSecurity set up as below

@Override
public void configure(WebSecurity web) throws Exception {
    web
        .ignoring()
        .antMatchers("/api/v0/auth/login");
}

or you can add url exclude to OncePerRequestFilter as below -

private final RequestMatcher uriMatcher = new AntPathRequestMatcher("/api/v0/auth/login", HttpMethod.GET.name());

@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
    return uriMatcher.matches(request);
}

CodePudding user response:

I guess you want to login with POST method, then you need explicitly say it in the method as i shown below

    http
         .csrf().disable()
         .antMatchers("HttpMethod.POST, /api/v0/auth/login").permitAll()
         ...

You can also try securing only needed endpoints

 http
            .authorizeRequests()
            .antMatchers("/secured").authenticated()
            .anyRequest()
            .permitAll();
  • Related