Search code examples
javaspringspring-bootspring-securityconfiguration

How to change Login URL in Spring Security


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


Solution

  • 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