Nikita Nova
Nikita Nova

Reputation: 15

JWT Token not generated after successful Authentication in Spring Boot

I created two filters to run for every request JwtUsernameAndPasswordFilter and JwtTokenVerifier. I have used these two filters before and they HAVE worked. I think the main issue is with my Spring Security Config. When I debug these two filters only JwtTokenVerified is recognized and JwtUsernameAndPasswordFilter does not get called at all. When I make a request from PostMan with a application/json content type the server would give me an error:

class path resource [templates/logIn.html] cannot be opened because it does not exist

/logIn Controller

@RequestMapping(value="/logIn",method = {RequestMethod.POST,RequestMethod.GET})
    public void login(){
    }

Spring Security Config

@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Configuration
@Builder
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private SecureUserDaoService secureUserDaoService;
    private JwtConfig jwtConfig;
    private SecretKey secretKey;
    private PasswordEncoder passwordEncoder;


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

                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

                .and()

                .addFilter(new JwtUsernameAndPasswordFilter(authenticationManager(), jwtConfig, secretKey))
                .addFilterAfter(new JwtTokenVerifier(secretKey, jwtConfig), JwtUsernameAndPasswordFilter.class)

                .authorizeRequests()

                .antMatchers("/accountPage", "/accountSettings").authenticated()
                .antMatchers("/", "/signUp", "/logIn").permitAll()
                .anyRequest().authenticated()
                .and()

                .formLogin()
                .failureUrl("/")
                .successForwardUrl("/accountPage");
    }

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

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider(){
        DaoAuthenticationProvider provider =
                new DaoAuthenticationProvider();
        provider.setPasswordEncoder(passwordEncoder);
        provider.setUserDetailsService(secureUserDaoService);
        return provider;
    }

github repo

UPDATE:

By calling "/login" instead of "/logIn" in the client made it work, because apparently even when I add .loginPage("/logIn") AND .logInProcessingUrl("/logIn").It seems like spring still does not recognize my custom login controller when it goes through the filter chain. Feel free to comment below if you know of a better solution

Upvotes: 0

Views: 3873

Answers (1)

jumping_monkey
jumping_monkey

Reputation: 7847

When I debug these two filters only JwtTokenVerified is recognized and JwtUsernameAndPasswordFilter does not get called at all.

JwtUsernameAndPasswordFilter is being called. To prove it, either put a debug statement in your filter or better, in your SecurityConfig.java, enable Spring Security debugger, like so:

@EnableWebSecurity(debug=true)

and you will see this:

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  LogoutFilter
  JwtUsernameAndPasswordFilter            // This is your filter
  UsernamePasswordAuthenticationFilter
  JwtTokenVerifier                        // This is your filter
  DefaultLoginPageGeneratingFilter
  DefaultLogoutPageGeneratingFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

When I make a request from PostMan with a application/json content type the server would give me an error:

class path resource [templates/logIn.html] cannot be opened because it does not exist

This is because in your /templates folder, there is no logIn.html.

By calling "/login" instead of "/logIn" in the client made it work, because apparently even when I add .loginPage("/logIn") AND .logInProcessingUrl("/logIn").It seems like spring still does not recognize my custom login controller when it goes through the filter chain. Feel free to comment below if you know of a better solution

/login works because since you did not define a custom login page in your SecurityConfig.java, Spring Security will redirect you to its default login page.

If you do not want that feature, you can customize the loginPage as follows:

.and()
.formLogin().loginPage("/customizeMe")   // Your custom login page here
.failureUrl("/")
.successForwardUrl("/accountPage");

Upvotes: 1

Related Questions