How to change Login URL in Spring Security

16,739

Solution 1

The function .loginProcessingUrl("/api/v1/login"), specifies the URL to validate the credentials, the URL to validate username and password.

It will only override url to /api/v1/login of POST type, not GET

It will not pass the request to Spring MVC and your controller

For additional customization you can have a look through FormLoginConfigurer

UPDATE v1

Can you also check if your urls under /api/** are all secured?

If yes then try removing the security from /api/v1/login and add permitAll() configuration to this url

Check this post - https://stackoverflow.com/a/27471722/2600196. if it helps your scenario

UPDATE v2 - this helped in the case here

you were not sending the username and password correctly and for that to work refer the things below, in your it was showing up BadCredentialsException. I enabled debug on the application and was able to figure that out.

you need to post the parameters to the url - http://localhost:8080/api/v1/login as below (have also attached the image, screenshot of postman):-

headers: Content-Type=application/x-www-form-urlencoded

parameters in key value pairs(not in json format, please refer the image):

username=player3
password=pass3

enter image description here

Above you can the response coming up from the index.html like below:-

<a href="http://localhost:8080/other.html">test static resource</a>

Which you also need to customize.

For Sending the JSON request for username and password, the changes that will work easily for you will be:-

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

    http.cors().and().csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers("/h2-console/**/**").permitAll()
        .antMatchers(HttpMethod.POST,"/user/register").permitAll()
        .antMatchers("/user/activate").permitAll()
        .antMatchers("/user/reset-password").permitAll()
        .antMatchers("/user/reset-password").permitAll()
        .antMatchers("/admin/user").hasRole("ADMIN")
        .antMatchers("/roles").permitAll()
        .antMatchers("/user/**").hasRole("USER")
        //.and()
        //.formLogin().loginProcessingUrl("/api/v1/login") // not required any more
        .and()
        .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
        .and()
        .addFilterBefore(new ExceptionHandlerFilter(), UsernamePasswordAuthenticationFilter.class)
        .addFilter(jwtAuthorizationFilter())
        .addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUserDetailService));
    
    http.headers().frameOptions().disable(); // its required for h2-console

}

public JwtAuthenticationFilter jwtAuthorizationFilter() throws Exception {
    JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager());
    jwtAuthenticationFilter.setFilterProcessesUrl("/api/v1/login");
    return jwtAuthenticationFilter;
}

And the code .formLogin().loginProcessingUrl("/api/v1/login") not required anymore

Further you need to add the success and the failure urls to the application, and to make your login url to fetch json based user credentials, you need to follow up and need to do some more stuff, some useful reference for that - https://stackoverflow.com/a/19501060/2600196

Solution 2

You are extending org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter which itself extendsorg.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter. In this last class, there is a setter called 

setFilterProcessesUrl

 which is intended to do just this:

setFilterProcessesUrl

public void setFilterProcessesUrl(String filterProcessesUrl)

Sets the URL that determines if authentication is required

Parameters: filterProcessesUrl

This is the link to that javadoc section

So in your WebSecurityConfigurerAdapter you could do just like this:

@Bean 
public JWTAuthenticationFilter getJWTAuthenticationFilter() { 
    final JWTAuthenticationFilter filter = new JWTAuthenticationFilter(authenticationManager()); 
    filter.setFilterProcessesUrl("/api/auth/login"); 
    return filter; 
}

And then in your configure method in the same class just reference it instead of creating new instance:

.addFilter(getJWTAuthenticationFilter
Share:
16,739

Related videos on Youtube

Samet Baskıcı
Author by

Samet Baskıcı

Updated on June 04, 2022

Comments

  • Samet Baskıcı
    Samet Baskıcı almost 2 years

    I created an API that provides User authentication and it's login operation is handled on default '/login' path by Spring Security.

    I want to change this path to 'api/v1/login'.

    this is my security config :

    http.cors().and().csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/h2-console/**/**").permitAll()
                .antMatchers(HttpMethod.POST,"/user/register").permitAll()
                .antMatchers("/user/activate").permitAll()
                .antMatchers("/user/reset-password").permitAll()
                .antMatchers("/user/reset-password").permitAll()
                .antMatchers("/admin/user").hasRole("ADMIN")
                .antMatchers("/roles").permitAll()
                .antMatchers("/user/**").hasRole("USER")
                .and()
                .formLogin().loginProcessingUrl("/api/v1/login")
                .and()
                .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
                .and()
                .addFilterBefore(new ExceptionHandlerFilter(), UsernamePasswordAuthenticationFilter.class)
                .addFilter(new JwtAuthenticationFilter(authenticationManager()))
                .addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUserDetailService));
    

    I have added this line to change it :

    .formLogin().loginProcessingUrl("/api/v1/login")
    

    But it is still working under '/login' path.

    "/api/v1/login" return 404.

    Is there any way to change it ?

    Spring Boot Version : 2.0.0.RELEASE

    • kakabali
      kakabali about 6 years
      .loginProcessingUrl("/api/v1/login") will override the /login post url to /api/v1/login where you will submit the credentials
    • Samet Baskıcı
      Samet Baskıcı about 6 years
      I am sending post request via postman,it doesn't override it, still working for '/login'.
    • kakabali
      kakabali about 6 years
      Post the complete url that you are trying and can you also share the screenshot of postman
    • Samet Baskıcı
      Samet Baskıcı about 6 years
    • kakabali
      kakabali about 6 years
      Can you also check if your urls under /api/** are all secured? If yes then try removing the security from /api/v1/login and add permitAll() configuration to this url
    • kakabali
      kakabali about 6 years
    • kakabali
      kakabali about 6 years
      also if you can check changing - @EnableWebSecurity to @EnableWebMvcSecurity as it has been asked by the person on that
    • kakabali
      kakabali about 6 years
      as you have shared in the screenshot that it is showing 404, but looks like your /api/v1/login is getting redirected to /login and in your application it is no more present because you override it, I can see in the response that it is giving "path":"/login", in the case of /api/v1/login it should have given "path":"/api/v1/login"
    • kakabali
      kakabali about 6 years
      don't you think like this?
    • Samet Baskıcı
      Samet Baskıcı about 6 years
      @kakabali Yes it redirects but why I cant reach service? whereas it is working for '/login' while I getting this error.
    • kakabali
      kakabali about 6 years
      I have added update to the answer please check