简体   繁体   中英

Spring Security 2 types of login

I am trying to have a user login and an administrator login. Currently only the administrator login works and the other one just outputs an error. I'm not quite sure why it is not working and if anyone could understand why it is not, could you let me know. Here is my security config.

@EnableWebSecurity
public class AdminSecurityConfig extends WebSecurityConfigurerAdapter {
 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
        .withUser("admin").password("12345").roles("ADMIN")
        .and()
        .withUser("tester").password("56789").roles("ADMIN");
        
    }
    @Override
 protected void configure(HttpSecurity http) throws Exception {
         http.authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers("/login")
            .permitAll()
                .antMatchers("/newUser")
                .permitAll()
                .antMatchers("/admin")
                .hasAnyRole("ADMIN")
            .and()
            .formLogin()
            .loginPage("/login1")
            .defaultSuccessUrl("/admin")
            .failureUrl("/login?error=true")
            .permitAll()
                .and()
                .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login2")
                .defaultSuccessUrl("/success")
                .failureUrl("/login?error==true")
                .permitAll()
                    .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/")
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(true) 
            .and()
                .csrf()
                .disable()

            ;
  }
         
    @Bean
    public UserDetailsService userDetailsService() {
        return new CustomUserDetailsService();
    }
    @Autowired
    public void configurationGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

And here is the login page for the user - the one that is not working.

<body id="body">
<div id="container">
<h1>Authorised Users Only</h1>
<div id="box">
<form:form name='user' action="/login2" method='POST'>

             <form:errors path="username" />
    
      <label for="username">Email address</label>
            <input type='text' class="form-control" name='username' value='' placeholder="Enter Email address"></td>
            <label for="password">Password: </label>
            <input type='password' class="form-control" name='password' /></td>
       
        
<input name="submit" class="btn btn-primary" type="submit" value="submit" /></td>
        

</form:form>

So when I type in username = "test" and password = "123" which are correct values it ouputs "error==true". Could anyone provide insight into anything that I could do to fix this.

Here is the requestMapping for "/succsess"

    @RequestMapping(value = "/success", method = RequestMethod.GET)
    public String successLogin() {
        return "redirect:/home";
    }
@RequestMapping("/home")
public String homepage( Model model) {
    model.addAttribute("vols", volrepo.findAll());
    return "Homepage";
}

Listing two .formLogin declarations does not do what you are thinking. Instead, you need two separate security configurations.

If you are using Spring Security 5.4, you can do:

@Bean
@Order(1)
SecurityFilterChain adminFilters(HttpSecurity http) throws Exception {
    http
        .requestMatchers((matchers) -> matchers.mvcMatchers("/admin/**"))
        .authorizeRequests((requests) -> requests.anyRequest().hasRole("ADMIN"))
        .formLogin((form) -> form
            .defaultSuccessUrl("/admin/home")
            .loginPage("/admin/login").permitAll()
        );

    return http.build();
}

@Bean
@Order(2)
SecurityFilterChain userFilters(HttpSecurity http) throws Exception {
    http
        .authorizeRequests((requests) -> requests.anyRequest().authenticated())
        .formLogin(Customizers.withDefaults());

    return http.build();
}

@Bean
UserDetailsService userDetailsService() { ... }

@Bean
PasswordEncoder passwordEncoder() { ... }

Or, if you are on an earlier version, you can publish two WebSecurityConfigurerAdapter s:

@Configuration
public class SecurityConfig {
    @Component
    @Order(1)
    static class AdminConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .requestMatchers((matchers) -> matchers.mvcMatchers("/admin/**"))
                .authorizeRequests((r) -> r.anyRequest().hasRole("ADMIN"))
                .formLogin((form) -> form
                    .defaultSuccessUrl("/admin/home")
                    .loginPage("/admin/login").permitAll()
                );

            return http.build();       
        }
    }

    @Component
    @Order(2)
    static class UserConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests((r) -> r.anyRequest().authenticated())
                .formLogin(Customizer.withDefaults());

            return http.build();       
        }
    }

    @Bean
    UserDetailsService userDetailsService() { ... }

    @Bean
    PasswordEncoder passwordEncoder() { ... }
}

Either way, the first filter chain will be invoked for any URL having the pattern /admin/** . If you choose to place all your admin pages in the same path, that makes so that you can have just the one matcher.

The second filter chain will be invoked for any other URL.

The UserDetailsService and PasswordEncoder will be shared by both filter chains.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM