SpringSecurity--记住我功能原理

记住我功能原理:

项目中记住我配置:

//记住我配置,如果想在'记住我'登录时记录日志,可以注册一个InteractiveAuthenticationSuccessEvent事件的监听器
http.rememberMe()
.tokenRepository(persistentTokenRepository())//保存方式
//国企时间				.tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds())
.userDetailsService(userDetailsService)//认证服务

   /**
	 * 记住我功能的token存取器配置
	 * @return
	 */
	@Bean
	public PersistentTokenRepository persistentTokenRepository() {
		JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
		tokenRepository.setDataSource(dataSource);
		//自动创建表
//		tokenRepository.setCreateTableOnStartup(true);
		return tokenRepository;
	}

 JdbcTokenRepositoryImpl:用于rememberme功能数据存储

public class JdbcTokenRepositoryImpl extends JdbcDaoSupport implements
		PersistentTokenRepository {
	// ~ Static fields/initializers
	// =====================================================================================

	/** Default SQL for creating the database table to store the tokens */
	public static final String CREATE_TABLE_SQL = "create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, "
			+ "token varchar(64) not null, last_used timestamp not null)";
	/** The default SQL used by the <tt>getTokenBySeries</tt> query */
	public static final String DEF_TOKEN_BY_SERIES_SQL = "select username,series,token,last_used from persistent_logins where series = ?";
	/** The default SQL used by <tt>createNewToken</tt> */
	public static final String DEF_INSERT_TOKEN_SQL = "insert into persistent_logins (username, series, token, last_used) values(?,?,?,?)";
	/** The default SQL used by <tt>updateToken</tt> */
	public static final String DEF_UPDATE_TOKEN_SQL = "update persistent_logins set token = ?, last_used = ? where series = ?";
	/** The default SQL used by <tt>removeUserTokens</tt> */
	public static final String DEF_REMOVE_USER_TOKENS_SQL = "delete from persistent_logins where username = ?";
。。。。。。。。。。。。。。。。。。。。。。。。。

sql:

CREATE TABLE `persistent_logins` (
  `username` varchar(64) NOT NULL,
  `series` varchar(64) NOT NULL,
  `token` varchar(64) NOT NULL,
  `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  步骤说明:

表单登陆页面存在:

<input name="remember-me" type="checkbox" value="true" />记住我</td>

在登陆成功调用登陆成功处理的时候会先调用rememberMeServices的loginSuccess方法。

AbstractAuthenticationProcessingFilter:
	protected void successfulAuthentication(HttpServletRequest request,
			HttpServletResponse response, FilterChain chain, Authentication authResult)
			throws IOException, ServletException {

		if (logger.isDebugEnabled()) {
			logger.debug("Authentication success. Updating SecurityContextHolder to contain: "
					+ authResult);
		}

		SecurityContextHolder.getContext().setAuthentication(authResult);
        //记住我操作
		rememberMeServices.loginSuccess(request, response, authResult);

		// Fire event
		if (this.eventPublisher != null) {
			eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
					authResult, this.getClass()));
		}

		successHandler.onAuthenticationSuccess(request, response, authResult);
	}
PersistentTokenBasedRememberMeServices:
protected void onLoginSuccess(HttpServletRequest request,
			HttpServletResponse response, Authentication successfulAuthentication) {
	String username = successfulAuthentication.getName();
       
	logger.debug("Creating new persistent login for user " + username);
   
	PersistentRememberMeToken persistentToken = new PersistentRememberMeToken(
			username, generateSeriesData(), generateTokenData(), new Date());
	try {
	    //创建表结构 并且将数据存储在数据库中
		tokenRepository.createNewToken(persistentToken);
		//添加cookie
		addCookie(persistentToken, request, response);
	}
	catch (Exception e) {
		logger.error("Failed to save persistent token ", e);
	}
}

 登陆成功。

下一次请求过来。先进入RememberMeAuthenticationFilter拦截器中,从请求里面拿去cookie中的数据,然后去数据中进行查找相应用户的数据,

RememberMeAuthenticationFilter:

PersistentTokenBasedRememberMeServices:
 

之后又进入了 RememberMeAuthenticationFilter。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值