Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SecurityConfig 2 success url for different Roles

I'm trying to use Spring Security, all worked with one role.

I want to redirect to 2 different sites depending of the ROLE, but the Framework always redirects to the last defaultSuccessUrl("/...")**. Could this be posible?

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
        throws Exception {
    auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN")
            .and().withUser("user").password("user").roles("USER");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/admin/**")
            .access("hasRole('ROLE_ADMIN')").and().formLogin()
            .defaultSuccessUrl("/admin**").loginPage("/")
            .failureUrl("/").usernameParameter("username")
            .passwordParameter("password").and().logout()
            .logoutSuccessUrl("/").and()
            .authorizeRequests().antMatchers("/user/**")
            .access("hasRole('ROLE_USER')").and().formLogin()
            .defaultSuccessUrl("/user**").loginPage("/")
            .failureUrl("/").usernameParameter("username")
            .passwordParameter("password").and().logout()
            .logoutSuccessUrl("/");
    http.csrf().disable();
}
}
like image 253
D4NI3LS Avatar asked Dec 01 '25 22:12

D4NI3LS


1 Answers

The best way to do this is to send the user to a URL and then create a controller that processes the default-target-url. For example, the following will send the user to /default:

http
    .formLogin()
        .defaultSuccessUrl("/default")

Now create a controller that handles the URL "/default". The controller should redirect or forward based upon rolls. Below is an example of using Spring MVC, but any type of controller will work (i.e. Struts, a Servlet, etc).

@Controller
public class DefaultController {
    @RequestMapping("/default")
    public String defaultAfterLogin(HttpServletRequest request) {
        if (request.isUserInRole("ROLE_ADMIN")) {
            return "redirect:/admin/";
        }
        return "redirect:/user/";
    }
}

The advantages to this approach are it is not coupled to any specific implementation of Security, it is not coupled to any specific MVC implementation, and it works easily with XML and Java Configuration approaches.

A few additional notes:

  • "/admin**" is an invalid URL to redirect to for defaultSuccessUrl
  • Consider improving the Java Configuration Readability by formatting your code
  • You have unnecessary configuration due to defaults.

Below is a cleaned up version of your code:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
        throws Exception {
        auth
           .inMemoryAuthentication()
               .withUser("admin")
                   .password("admin")
                   .roles("ADMIN")
                   .and()
               .withUser("user")
                   .password("user")
                   .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasRole("USER")
                .and()
             .formLogin()
                .defaultSuccessUrl("/default")
                .loginPage("/")
                .failureUrl("/")
                .and()
            .logout()
                .logoutSuccessUrl("/")
                .and()
            // It is generally BAD to disable CSRF protection!
            .csrf().disable();
     }
}
like image 142
Rob Winch Avatar answered Dec 04 '25 12:12

Rob Winch



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!