spring-security-oauth2(五) 记住我

添加记住我功能

  1. 记住我功能基本原理
  2. 实现记住我功能
  3. 记住我SpringSecurity源码分析

1.记住我功能基本原理

过滤器链

 

 2.实现记住我功能 

给登录界面添加记住我选项

<html>
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<h2>标准登录页面</h2>
<h3>表单登录</h3>
<form action="/authentication/form" method="post">
    <table>
        <tr>
            <td>用户名:</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>图形验证码:</td>
            <td>
                <input type="text" name="imageCode">
                <img src="/captcha/image">
            </td>
        </tr>
        <tr>
            <td colspan="2"><input type="checkbox" name="remember-me" value="true"/>记住我</td>
        </tr>
        <tr>
            <td colspan="2">
                <button type="submit">登录</button>
            </td>
        </tr>
    </table>
</form>
</body>
</html>

注意记住我的name要固定  源码如下:

public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>>
      extends AbstractHttpConfigurer<RememberMeConfigurer<H>, H> {
   /**
    * The default name for remember me parameter name and remember me cookie name
    */
   private static final String DEFAULT_REMEMBER_ME_NAME = "remember-me";
}

浏览器配置中添加可配置的失效时间

package com.rui.tiger.auth.core.properties;

import com.rui.tiger.auth.core.model.enums.LoginTypeEnum;

/**
 * 浏览器配置
 *
 * @author CaiRui
 * @date 2018-12-6 8:42
 */
public class BrowserProperties {
	/**
	 * 登录页面 不配置默认标准登录界面
	 */
	private String loginPage = "/tiger-login.html";
	/**
	 * 跳转类型 默认返回json数据
	 */
	private LoginTypeEnum loginType = LoginTypeEnum.JSON;

	/**
	 * 记住我秒数
	 * @return
	 */
    private int remberMeSeconds=3600;

	public String getLoginPage() {
		return loginPage;
	}

	public void setLoginPage(String loginPage) {
		this.loginPage = loginPage;
	}

	public LoginTypeEnum getLoginType() {
		return loginType;
	}

	public void setLoginType(LoginTypeEnum loginType) {
		this.loginType = loginType;
	}

	public int getRemberMeSeconds() {
		return remberMeSeconds;
	}

	public void setRemberMeSeconds(int remberMeSeconds) {
		this.remberMeSeconds = remberMeSeconds;
	}
}

依据记住我原理对配置类进行修改

package com.rui.tiger.auth.browser.config;

import com.rui.tiger.auth.core.authentication.TigerAuthenticationFailureHandler;
import com.rui.tiger.auth.core.authentication.TigerAuthenticationSuccessHandler;
import com.rui.tiger.auth.core.captcha.CaptchaFilter;
import com.rui.tiger.auth.core.properties.SecurityProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

/**
 * 浏览器security配置类
 *
 * @author CaiRui
 * @date 2018-12-4 8:41
 */
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private SecurityProperties securityProperties;
	@Autowired
	private TigerAuthenticationFailureHandler tigerAuthenticationFailureHandler;
	@Autowired
	private TigerAuthenticationSuccessHandler tigerAuthenticationSuccessHandler;
	@Autowired
	private DataSource dataSource;
	@Autowired
	private UserDetailsService userDetailsService;

	/**
	 * 密码加密解密
	 *
	 * @return
	 */
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	/**
	 * 记住我持久化数据源
	 * JdbcTokenRepositoryImpl  CREATE_TABLE_SQL 建表语句可以先在数据库中执行
	 *
	 * @return
	 */
	@Bean
	public PersistentTokenRepository persistentTokenRepository() {
		JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
		jdbcTokenRepository.setDataSource(dataSource);
		//第一次会执行CREATE_TABLE_SQL建表语句 后续会报错 可以关掉
		//jdbcTokenRepository.setCreateTableOnStartup(true);
		return jdbcTokenRepository;
	}


	@Override
	protected void configure(HttpSecurity http) throws Exception {
		//加入图片验证码过滤器
		CaptchaFilter captchaFilter = new CaptchaFilter();
		captchaFilter.setFailureHandler(tigerAuthenticationFailureHandler);
		captchaFilter.setSecurityProperties(securityProperties);
		captchaFilter.afterPropertiesSet();

		//图片验证码放在认证之前
		http.addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class)
				.formLogin()
				.loginPage("/authentication/require")//自定义登录请求
				.loginProcessingUrl("/authentication/form")//自定义登录表单请求
				.successHandler(tigerAuthenticationSuccessHandler)
				.failureHandler(tigerAuthenticationFailureHandler)
				.and()
				//记住我相关配置
				.rememberMe()
				.tokenRepository(persistentTokenRepository())
				.tokenValiditySeconds(securityProperties.getBrowser().getRemberMeSeconds())
				.userDetailsService(userDetailsService)
				.and()
				.authorizeRequests()
				.antMatchers(securityProperties.getBrowser().getLoginPage(),
						"/authentication/require", "/captcha/image")//此路径放行 否则会陷入死循环
				.permitAll()
				.anyRequest()
				.authenticated()
				.and()
				.csrf().disable()//跨域关闭
		;
	}

}

下面我们来测试下,项目启动后可以看到用户token关系表已经建好了

 我们再前面登录,勾选记住我功能

 

成功登录后,可以看见后台已经保存关系了 

再访问我们的用户信息可以成功访问,接下来我们退出浏览器或重新启动项目,再次访问用户信息 还是可以成功访问 说明我们的记住我功能成功实现

3.记住我SpringSecurity源码分析

猜你喜欢

转载自blog.csdn.net/ahcr1026212/article/details/84981801