配置Spring Security以使用两个不同的登录页面

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了配置Spring Security以使用两个不同的登录页面相关的知识,希望对你有一定的参考价值。

我们可能需要两个登录页面的情况之一是,我们为应用程序的管理员提供一个页面,为普通用户提供不同的页面。每个http元素都有不同的登录页面和不同的登录处理URL

我有这个Spring启动安全配置允许登录多个页面。

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

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

        public App1ConfigurationAdapter() {
            super();
        }

        @Autowired
        private BCryptPasswordEncoder bCryptPasswordEncoder;

        @Autowired
        private DataSource dataSource;

        @Value("${admin-users-query}")
        private String usersQuery;

        @Value("${admin-roles-query}")
        private String rolesQuery;

        @Override
        protected void configure(AuthenticationManagerBuilder auth)
                throws Exception {
            auth.
                    jdbcAuthentication()
                    .usersByUsernameQuery(usersQuery)
                    .authoritiesByUsernameQuery(rolesQuery)
                    .dataSource(dataSource)
                    .passwordEncoder(bCryptPasswordEncoder);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/admin*")
                    .authorizeRequests()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .formLogin()
                    .loginPage("/admin/temp/login")
                    .failureUrl("//admin/temp?error=loginError")
                    .defaultSuccessUrl("/")
                    .usernameParameter("email")
                    .passwordParameter("password")
                    .permitAll()
                    .and()
                    .logout()
                    .logoutUrl("/admin/temp/logout")
                    .logoutSuccessUrl("/admin/temp")
                    .and()
                    .exceptionHandling()
                    .accessDeniedPage("/403").and().csrf();
        }
    }

    @Configuration
    @Order(2)
    public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Autowired
        private BCryptPasswordEncoder bCryptPasswordEncoder;

        @Autowired
        private DataSource dataSource;

        @Value("${user-users-query}")
        private String usersQuery;

        @Value("${user-roles-query}")
        private String rolesQuery;

        @Override
        protected void configure(AuthenticationManagerBuilder auth)
                throws Exception {
            auth.
                    jdbcAuthentication()
                    .usersByUsernameQuery(usersQuery)
                    .authoritiesByUsernameQuery(rolesQuery)
                    .dataSource(dataSource)
                    .passwordEncoder(bCryptPasswordEncoder);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/user*")
                    .authorizeRequests()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .formLogin()
                    .loginPage("/user/temp/login")
                    .failureUrl("/user/temp/?error=loginError")
                    .defaultSuccessUrl("/user/temp")
                    .usernameParameter("username")
                    .passwordParameter("password")
                    .permitAll()
                    .and()
                    .logout()
                    .logoutUrl("/user/temp/logout")
                    .logoutSuccessUrl("/user/temp/login")
                    .and()
                    .exceptionHandling()enter code here
                    .accessDeniedPage("/403").and().csrf();
        }
    }

    @Configuration
    @Order(3)
    public static class guestSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .anyRequest().permitAll();

        }

        @Override
        public void configure(WebSecurity web) throws Exception {
            web
                    .ignoring().antMatchers("/js/**", "/js/***", "/js/****");
        }
    }

管理员登录表单/ admin / temp / login

<form th:action="@{/admin/temp/login}" method="post">
                                        <div class="input-group mb-3">
                                            <span class="input-group-addon"><i class="icon-envelope"></i></span>
                                            <input type="text" class="form-control" placeholder="Email" name="email" data-validation="required" />
                                        </div>
                                        <div class="input-group mb-4">
                                            <span class="input-group-addon"><i class="icon-lock"></i></span>
                                            <input type="password" class="form-control" placeholder="Password" name="password"  data-validation="required" />
                                        </div>
                                        <div class="row">
                                            <div class="col-6">
                                                <input type="submit" class="btn btn-primary px-4" value="Login">
                                            </div>
                                            <div class="col-6 text-right">
                                                <a href="#" class="btn btn-link px-0">Forgot password?</a>
                                            </div>
                                        </div>
                                    </form>

用户登录表单/ user / temp / login

<form th:action="@{/user/temp/login}" method="post">
                                        <div class="input-group mb-3">
                                            <span class="input-group-addon"><i class="icon-envelope"></i></span>
                                            <input type="text" class="form-control" placeholder="Email" name="username" data-validation="required" />
                                        </div>
                                        <div class="input-group mb-4">
                                            <span class="input-group-addon"><i class="icon-lock"></i></span>
                                            <input type="password" class="form-control" placeholder="Password" name="password"  data-validation="required" />
                                        </div>
                                        <div class="row">
                                            <div class="col-6">
                                                <input type="submit" class="btn btn-primary px-4" value="Login">
                                            </div>
                                            <div class="col-6 text-right">
                                                <a href="#" class="btn btn-link px-0">Forgot password?</a>
                                            </div>
                                        </div>
                                    </form>

当我提交表格时,我得到了

**Code: 405
(Method Not Allowed)**

When I use single form the form get submted.

Does anyone has an idea on whats happening her?
答案

有人已经回答你需要添加

               .loginPage("/login.html")  
               .loginProcessingUrl("/admin/temp/login")

Spring登录将POST以触发身份验证过程的默认URL是/ login,它曾是Spring Security 4之前的/ j_spring_security_check。

另一答案

默认情况下,Spring假定验证凭据的URL是/login。要更改它,您应该为两个loginProcessingUrl配置设置formLogin

它应该是这样的:

.formLogin()
.loginPage("/user/temp/login")
.failureUrl("/user/temp/?error=loginError")
.defaultSuccessUrl("/user/temp")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/user/temp/login") # missing line

以上是关于配置Spring Security以使用两个不同的登录页面的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 推荐的设计以请求用户登录到具有不同角色的不同用户

Spring Security - OAuth2 和 CustomAuthenticationProvider。如何为每个配置不同的 URL 模式?

如何使用 spring-security-saml2 配置服务提供者以使用 EncryptedAssertions?

Spring REST security - 以不同的方式保护不同的 URL

spring security 使用hibernate和jsf认证不同的配置文件和权限

如何配置 Spring Security 以允许在 JSP 页面中使用 hasPermission?