SpringSecurity学习笔记之五:认证用户

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/zhoucheng05_13/article/details/60467435

  如果我们使用如下的最简单的配置,那么就能无偿地得到一个登陆页面:

package spitter.config;
......
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{}

  实际上,在重写configure(HttpSecurity)之前,我们都能使用一个简单却功能完备的登录页。但是,一旦重写了configure(HttpSecurity)方法,就是失去了这个简单的登录界面。不过,这个功能要找回也容易。我们只需要在configure(HttpSecurity)方法中,调用formLogin(),如下所示:

@Override
protected void configure(HttpSecurity http) throws Exception{
    http
      .formLogin()
       .and()
       .authorizeRequests()
         .antMatchers("/spitter/me").hasRole("SPITTER")
         .antMatchers(HttpMethod.POST,"/spittles").hasRole("SPITTER")
         .anyRequest().permitAll()
       .and()
         .requiresChannel()
         .antMatchers("/spitter/form").requiresSecure();   
}

  如果我们访问应用的“/login”链接或者导航到需要认证的页面,那么将会在浏览器中展现登录界面。这个界面在审美上没什么令人兴奋的,但是它却能实现所需的功能。

添加自定义的登录页

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
  <head>
    <title>Spitter</title>
    <link rel="stylesheet" 
          type="text/css" 
          th:href="@{/resources/style.css}"></link>
  </head>
  <body onload='document.f.username.focus();'>
    <div id="header" th:include="page :: header"></div>
  <div id="content">

    <a th:href="@{/spitter/register}">Register</a>


  <form name='f' th:action='@{/login}' method='POST'>
   <table>
    <tr><td>User:</td><td>
        <input type='text' name='username' value='' /></td></tr>
    <tr><td>Password:</td>
        <td><input type='password' name='password'/></td></tr>
    <tr><td colspan='2'>
    <input id="remember_me" name="remember-me" type="checkbox"/>
    <label for="remember_me" class="inline">Remember me</label></td></tr>
    <tr><td colspan='2'>
        <input name="submit" type="submit" value="Login"/></td></tr>
   </table>
  </form>
  </div>
  <div id="footer" th:include="page :: copy"></div>
  </body>
</html>

启用HTTP Basic认证

  如果要启用HTTP Basic认证的话,只需要在configure()方法所传入的HttpSecurity对象上调用httpBasic()即可。另外,还可以通过调用realmName()方法指定域。如下是在Spring Security中启用HTTP Basic认证的典型配置:

@Override
protected void configure(HttpSecurity http) throws Exception{
    http
      .formLogin()
        .loginPage("/login")
      .and()
      .httpBasic()
         .realmName("Spittr")
      .and()
      ...
}

在httpBasic()方法中,并没有太多的可配置项,甚至不需要什么额外配置。HTTP Basic认证要么开启,要么关闭。

启用Remember-me功能

  站在用户的角度来讲,如果应用程序不用每次都提示他们登录是更好的。这就是为什么许多站点提供了Remember-me功能。你只要登录过一次,应用就会记住你。
  Spring Security使得为应用添加Remember-me功能变得非常容易。只需要在configure()方法所传入的HttpSecurity对象上调用rememberMe()即可。

@Override
protected void configure(HttpSecurity http) throws Exception{
    http
      .formLogin()
        .loginPage("/login")
      .and()
      .rememberMe()
         .tokenValiditySeconds(2419200)
         .key("spittrKey")
  ...
}

  默认情况下,这个功能是通过在Cookie中存储一个token完成的,这个token最多两周内有效。但是,在这里,我们指定这个token最多四周内有效(2,419,200秒)。存储在cookie中的token包含用户名、密码、过期时间和一个私匙——在写入cookie前都进行了MD5哈希。默认情况下,私匙的名为SpringSecured,但是这里我们将其设置为spitterKey,使他专门用于Spittr应用。
  既然Remember-me功能已经启用,我们需要有一种方式来让用户表明他们希望应用程序记住他们。为了实现这一点,登录请求必须包含一个名为remember-me的参数。在登录表单中,增加一个简单复选框就可以完成这件事:

<input id="remember-me" name="remember-me" type="checkbox"/>
<lable for="remember-me" class="inline">Remember me</label>

退出

  其实,按照我们的配置,退出功能已经可以使用了,不需要再做其他的配置了。我们需要的只是一个使用该功能的链接。
  退出功能是通过Servlet容器的Filter实现的(默认情况下),这个Filter会拦截针对“/logout”的请求。在新版本的SpringSecurity中,出于安全的考虑(防止CSRF攻击),已经修改了LogoutFilter,使得Get方式的“/logout”请求不可用。必须以POST方式发起对该链接的请求才能生效。因此,为应用添加退出功能只需要添加如下表单即可(如下以Thymeleaf代码片段的形式进行了展现):

<form th:action="@{/logout}" method="POST">
   <button type="submit">退出登录</button>
</form>

   提交这个表单,会发起对“/logout”的请求,这个请求会被Spring Security的LogoutFilter所处理。用户会退出应用,所有的Remember-me token都会被清楚掉。在退出完成后,用户浏览器将会重定向到“/login?logout”,从而允许用户进行再次登录。如果希望被重定向到其他的页面,如应用的首页,那么可以在configure()中进行配置:

@Override
protected void configure(HttpSecurity http) throws Exception{
    http
      .formLogin()
        .loginPage("/login")
      .and()
      .logout()
         .logoutSuccessUrl("/")
  ...
}

除了logoutSuccessUrl()方法之外,你可能还希望重写默认的LogoutFilter拦截路径。我们可以通过调用logoutUrl()方法实现这一功能:

.logout()
   .logoutSuccessUrl("/")
   .logoutUrl("/signout")



上一篇:SpringSecurity学习笔记之四:拦截请求
下一篇:SpringSecurity学习笔记之六:保护视图

展开阅读全文

没有更多推荐了,返回首页