Home > Back-end >  How to skip oncePerRequestFilter and run login rest endpoint
How to skip oncePerRequestFilter and run login rest endpoint

Time:03-12

I'm trying to learn spring security but stuck on filters. I know that oncePerRequestFilter works for each request and I'm planning to check JWT token in this filter. But if user is new and tries to reach /auth/login endpoint then somehow I need to say this filter to allow, then execute my method for /auth/login. But I couldn't find to way to run that method.

This is my OncePerRequestFilter

public class JwtAuthenticationFilter extends OncePerRequestFilter {


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        System.out.println("JwtAuthenticationFilter.doFilterInternal is working");

        if(request.getServletPath().equals("/auth/login")) {
            System.out.println("if there is a request to /auth/login just continue");
            filterChain.doFilter(request, response);
        }
        // else continue to check JWT token

    }
}

my endpoint

@AllArgsConstructor
@RestController("/auth")
public class LoginController {

    private final AuthenticationManager authenticationManager;

    @PostMapping("/login")
    public LoginTokenResponse login(@RequestBody LoginRequest loginRequest) {

        System.out.println("login method is working");

        if(loginRequest == null) {
            throw new IllegalArgumentException("No credentials provided");
        }

        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword());
        Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        
       // do other things and return LoginResponseToken

        return null;

    }

    @GetMapping("/ping")
    public String ping() {
        System.out.println("pong is working");
        return "pong";
    }
}

and WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final PasswordCheckUserDetailService passwordCheckUserDetailService;

    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
        builder.userDetailsService(passwordCheckUserDetailService)
                .passwordEncoder(UserPasswordEncoder.getUserPasswordEncoder());

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.cors().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.authorizeRequests().antMatchers(HttpMethod.POST,  "/auth/login/**").permitAll();
        http.authorizeRequests().anyRequest().authenticated();

        JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter();

        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

and when I make post request to /auth/login I'm getting below response and login method is not working at all. (Doesn't print)

{
    "timestamp": "2022-03-12T00:59:38.932 00:00",
    "status": 404,
    "error": "Not Found",
    "message": "No message available",
    "path": "/auth/login"
}

if you want to inspect other parts: https://github.com/xsenko/JWTAuthentication/tree/develop/src/main/java/com/senko/JWTAuthentication

CodePudding user response:

@RestController("/auth") - it's for a logical component name, not for request mapping.
You should use @RequestMapping("/auth")

  • Related