Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm using Spring Security 3.2.1.RELEASE with Spring MVC 4.0.4.RELEASE

I'm trying to setup Spring Security for a web application that will have two distinct login entry pages. I need the pages to be distinct as they will be styled and accessed differently.

First login page is for Admin users and protects admin pages /admin/**

Second login page is for Customer users and protects customer pages /customer/**.

I've attempted to setup two subclasses of WebSecurityConfigurerAdapter configuring individual HttpSecurity objects.

CustomerFormLoginWebSecurity is protecting customer pages and redirecting to customer login page if not authorised. The AdminFormLoginWebSecurity is protecting admin pages redirecting to admin login page if not authorised.

Unfortunately it seems that only the first of the configurations is enforced. I think that I am missing something extra to make these both work.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    public void registerGlobalAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser("customer").password("password").roles("CUSTOMER").and()
                .withUser("admin").password("password").roles("ADMIN");
    }

    @Configuration
    @Order(1)
    public static class CustomerFormLoginWebSecurity extends WebSecurityConfigurerAdapter {

        @Override
        public void configure(WebSecurity web) throws Exception {
            web
                    .ignoring()
                    .antMatchers("/", "/signin/**", "/error/**", "/templates/**", "/resources/**", "/webjars/**");
        }

        protected void configure(HttpSecurity http) throws Exception {
            http
                    .csrf().disable()
                    .authorizeRequests()
                    .antMatchers("/customer/**").hasRole("CUSTOMER")
                    .and()
                    .formLogin()
                    .loginPage("/customer_signin")
                    .failureUrl("/customer_signin?error=1")
                    .defaultSuccessUrl("/customer/home")
                    .loginProcessingUrl("/j_spring_security_check")
                    .usernameParameter("j_username").passwordParameter("j_password")
                    .and()
                    .logout()
                    .permitAll();

            http.exceptionHandling().accessDeniedPage("/customer_signin");
        }
    }

    @Configuration
    public static class AdminFormLoginWebSecurity extends WebSecurityConfigurerAdapter {
        @Override
        public void configure(WebSecurity web) throws Exception {
            web
                    .ignoring()
                    .antMatchers("/", "/signin/**", "/error/**", "/templates/**", "/resources/**", "/webjars/**");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .csrf().disable()
                    .authorizeRequests()
                    .antMatchers("/admin/**").hasRole("ADMIN")
                    .and()
                    .formLogin()
                    .loginPage("/admin_signin")
                    .failureUrl("/admin_signin?error=1")
                    .defaultSuccessUrl("/admin/home")
                    .loginProcessingUrl("/j_spring_security_check")
                    .usernameParameter("j_username").passwordParameter("j_password")
                    .and()
                    .logout()
                    .permitAll();

            http.exceptionHandling().accessDeniedPage("/admin_signin");
        }
    }

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
170 views
Welcome To Ask or Share your Answers For Others

1 Answer

The component of the spring login chain that redirects to a login page is the authentication filter, and the filter that get's plugged in when using http.formLogin() is DefaultLoginPageGeneratingFilter.

This filter either redirects to the login url or builds a default basic login page, if no login page url is provided.

What you need then is a custom authentication filter with the logic to define which login page is needed, and then plug it in the spring security chain in place of the single page authentication filter.

Consider creating a TwoPageLoginAuthenticationFilter by subclassing DefaultLoginPageGeneratingFilter and overriding getLoginPageUrl(), and if that is not sufficient then copy the code and modify it to meet your needs.

This filter is a GenericFilterBean, so you can declare it like this:

@Bean
public Filter twoPageLoginAuthenticationFilter() {
    return new TwoPageLoginAuthenticationFilter();
}

then try building only one http configuration and don't set formLogin(), but instead do:

http.addFilterBefore(twoPageLoginAuthenticationFilter, ConcurrentSessionFilter.class);

and this will plug the two form authentication filter in the right place in the chain.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...