如何使用 Spring Security 自定义登录页面?

Posted

技术标签:

【中文标题】如何使用 Spring Security 自定义登录页面?【英文标题】:How to use Spring Security to custom login page? 【发布时间】:2017-06-06 20:00:25 【问题描述】:

我在我的应用程序中使用 Spring Security,这是对用户进行身份验证的安全部分,但登录页面由 Spring Security 提供:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 
    public void configure(HttpSecurity httpSecurity) throws Exception 
        httpSecurity
            .authorizeRequests()
                .antMatchers("/home*").hasRole("USER")
                .and()
            .formLogin();

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
        auth
            .inMemoryAuthentication()
                 .withUser("user")
                 .password("password")
                 .roles("USER")
    

我想使用下面的登录页面,而不是 Spring 的登录页面:

login.html:

<html lang='en'>
    <head>
        <title>WebApp</title>
        <meta charset='utf-8' />

        <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
             <link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
             <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
             <link rel="stylesheet" href="css/login.css" />  
    </head>

    <body>
        <div class="login-page">
            <img src='img/taxi_.jpg' style='width: 180px; margin-left: auto; margin-right: auto; display: block; padding-top: 20px; padding-bottom:20px;' />

            <div class="heading">
                <center>Dashboard</center>
            </div>
            <div class="form">
                <form action ="home.html" class="register-form">
                    <input type="text" placeholder="name"/>
                    <input type="password" placeholder="password"/>
                    <input type="text" placeholder="email address"/>
                    <button>create</button>
                    <p class="message">Already registered? <a href="#">Sign In</a></p>
               </form>
               <form action="home.html" class="login-form">
                    <input type="text" placeholder="username"/>
                    <input type="password" placeholder="password"/>
                    <button id="button_login">login</button>
                    <p class="message">Not registered? <a href="#">Create an account</a></p>
               </form>
            </div>
        </div>
    </body>
</html>

如何使用我的自定义登录页面而不是 Spring Security 的登录页面来显示?

【问题讨论】:

我试过httpSecurity.authorizeRequests().antMatchers("/home*").hasRole("USER") .and() .formLogin().loginPage("login.html")。但它返回了相同的春季登录页面。 将登录页面更改为我的自定义页面,而不是 Spring Security 的默认页面 你必须确保url "/login.html" 可以被正确处理 【参考方案1】:

只是想指出这里没有澄清的一些时刻。

    首先,.loginPage("/login.html") 不会奏效(无论如何,在我的情况下它没有)。此处引号中的内容是将在您的控制器中搜索的 URL 路径。这是我的安全配置文件中的 sn-p:

     .formLogin().loginPage("/login")
     .loginProcessingUrl("/authentication").permitAll();
    

我在这里写了"/login"。所以现在在你的控制器中定义/login 路径应该指向你的login.html 页面。

    @GetMapping("/login")
    public String login() 
        return "login";
    

只有这样它才应该重定向到所需的视图页面。我通常将视图页面放在/webapp/WEB-INF/view 文件夹下。 附言我希望你正确配置了ViewResolver bean,否则它将无法工作:)

    还有一件事。我看到你想为页面使用一些 CSS。要为您的自定义登录页面启用 CSS 和其他静态资源,您应该添加此行

.antMatchers("/resources/**").permitAll()

所以,最终会是这样(非常简短且令人毛骨悚然的版本,但您的自定义登录应该可以工作):

@Override
protected void configure(HttpSecurity http) throws Exception 
    http
        .authorizeRequests()
            .antMatchers("/resources/**").permitAll()
            .anyRequest().authenticated()
            .and()

        .formLogin().loginPage("/login")
        .loginProcessingUrl("/authentication").permitAll();

仅供参考,请将您的资源放在/webapp/resources/ 下。此外,您应该在 spring 配置文件中配置资源处理程序。

这也是一个很好的链接,可以让您了解它:

https://docs.spring.io/spring-security/site/docs/current/guides/html5/form-javaconfig.html#grant-access-to-remaining-resources

【讨论】:

【参考方案2】:

见Spring Security Reference:

虽然自动生成的登录页面便于快速启动和运行,但大多数应用程序都希望提供自己的登录页面。为此,我们可以更新我们的配置,如下所示:

protected void configure(HttpSecurity http) throws Exception 
  http
      .authorizeRequests()
          .anyRequest().authenticated()
          .and()
      .formLogin()
          .loginPage("/login") 1
          .permitAll();        2

1更新后的配置指定了登录页面的位置。2我们必须授予所有用户(即未经身份验证的用户)访问我们登录页面的权限. formLogin().permitAll() 方法允许向所有用户授予与基于表单的登录关联的所有 URL 的访问权限。

您修改后的代码:

public void configure(HttpSecurity httpSecurity) throws Exception 
    httpSecurity
        .authorizeRequests()
            .antMatchers("/home*").hasRole("USER")
            .and()
        .formLogin()
            .loginPage("/login.html")
            .permitAll();

【讨论】:

【参考方案3】:
httpSecurity.authorizeRequests()
                .antMatchers("/home*").hasRo‌​le("USER").and()                                          
             .formLogin()
                 .loginPage("/login.html")
                 .permitAll();

loginFormUrl 必须以“/”或绝对 URL 开头。并确保可以正确处理请求/login.html

顺便说一句:如果你没有配置处理 url,处理 url 将与 login page(/login.html) url 相同 post 方法,但在你的登录页面中,操作 url 是/home.html ,请将处理url配置为'/home.html'

.formLogin()
    .loginProcessingUrl("/home.html")
    .loginPage("/login.html")
    .permitAll();

并且CSRF 默认启用,我在您的登录表单中找不到任何CSRF 令牌。您可以禁用 csrf 或使用令牌请求。

http.csrf().disable();

【讨论】:

请看here

以上是关于如何使用 Spring Security 自定义登录页面?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用自定义登录页面纠正 Spring Security 异常?

如何使用自定义 JAAS 堆栈配置 Spring Security?

如何在 Spring Security 中使用自定义角色/权限?

如何使用我自己的机制自定义 spring-security 身份验证过程

如何使用 grails 1.3.2 和插件 spring-security-core 1 实现自定义 FilterSecurityInterceptor?

Spring Security 3-如何自定义用户名/密码参数?