Spring Security教程(七)

在之前的教程四中一笔带过式的讲了下RememberMe记住密码的功能,那篇的Remember功能是最简易的配置,其功能和安全性都不强。这里就配置下security中RememberMe的各种方式。本人也是在学习中,若有错误,欢迎指正,一起学习。

一 概述

RememberMe 是指用户在网站上能够在 Session 之间记住登录用户的身份的凭证,通俗的来说就是用户登陆成功认证一次之后在制定的一定时间内可以不用再输入用户名和密码进行自动登录。这个过程中通过服务端发送一个 cookie 给客户端浏览器保存,下次浏览器再访问服务端时服务端能够自动检测客户端的 cookie,根据 cookie 值触发自动登录操作。Spring Security中的 Remember-Me 功能通常有两种实现方式。一种是简单的使用加密来保证基于 cookie 的 token 的安全,另一种是通过数据库或其它持久化存储机制来保存生成的 token。
两种方式的区别:第一中方式不安全,就是说在用户获取到实现记住我功能的 token 后,任何用户都可以在该 token 过期之前通过该 token 进行自动登录。如果用户发现自己的 token 被盗用了,那么他可以通过改变自己的登录密码来立即使其所有的记住我 token 失效。如果希望我们的应用能够更安全,那就使用第二种方式。第二种方式也是详细要讲解的。

二 基于简单加密的方式

需要特别注意的是,这两种方式在配置的时候都要提供一个UserDetailsService,这个东西其实就是之前配置的jdbc-user-service标签的一个实现类,配置代码如下:

		
		
		
	
说明:dataSource就是连接数据库的数据源;usersByUsernameQuery就是配置 jdbc-user-service时候的users-by-username-query,这个是根据用户名来查询用户的sql语句;同理authoritiesByUsernameQuery就是对应的authorities-by-username-query,这个用来根据用户名查询对应的权限。
下面来配置rememberMe的过滤器:

	
		
		
	
这个过滤器仅仅这样配置是不会起作用的,还要把它加入的Security的FilterChain中去,用即可,另外这个过滤器要提供一个rememberMeServices和一个用户认证的authenticationManager,后面这个其实就是authentication-manager所配置的东西,而前面这个需要另外配置,配置方式如下:

      
      
      
      
   
这个配置中的userDetailsService就是上面配置的,直接引用上面的即可;key就是token中的key,这个key可以用来方式token被修改,另外这个key要和后面配置的rememberMeAuthenticationProvider的key要一样;parameter就是登陆界面的点击记住密码的checkbox的name值,这个一定要一直,要不然没有效果的。
初次之外还要配置一个用户记住密码做认证的authenticationManager

      
   
同时还要将其添加到authentication-manager标签中去

		
		
		
		
	
最后面将rememberMeServices添加到myUsernamePasswordAuthenticationFilter中去。
最终的配置文件如下:


	
	
	
		
		
		
			
		
		
		
	
	
		
	
	
	
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	
	
	
		
		
	

	
		
		
		
		
		
	

	
		
	

	
		
	


	
	
		
		
		
		
		
		
	

	
	
	
	
	
		
	
	
	
		
		
		
	
	
	
		
		
	
	
	
	
		
		
		
		
      
	
	
	
	
		
	
	
		
	
	

因为这个例子是在之前的例子上进行修改的,所以其它的没讲到的一些配置在之前博客都有详细的讲解,请参考之前的博客。

二 基于持久化的方式配置

在将这配置之前先对上面rememberService中的实现类TokenBasedRememberMeServices进行简单的讲解,该类主要是基于简单加密 token 的一个实现类。TokenBasedRememberMeServices 会在用户选择了记住我成功登录后,生成一个包含 token 信息的 cookie 发送到客户端;如果用户登录失败则会删除客户端保存的实现 Remember-Me 的 cookie。需要自动登录时,它会判断 cookie 中所包含的关于 Remember-Me 的信息是否与系统一致,一致则返回一个 RememberMeAuthenticationToken 供 RememberMeAuthenticationProvider 处理,不一致则会删除客户端的 Remember-Me cookie。TokenBasedRememberMeServices 还实现了 Spring Security 的 LogoutHandler 接口,所以它可以在用户退出登录时立即清除 Remember-Me cookie。

而基础持久化方式配置的实质就是这个类不同,基于持久化方式配置的所用的实现类为:PersistentTokenBasedRememberMeServices,一看名字就知道其作用,就是将token进行持久化保存起来,要保存数据相应的就是为其制定保存的地方,这个保存的地方就是用PersistentTokenRepository来指定的,Spring Security 对此有两种实现,InMemoryTokenRepositoryImpl 和 JdbcTokenRepositoryImpl。前者是将 token 存放在内存中的,通常用于测试,而后者是将 token 存放在数据库中。PersistentTokenBasedRememberMeServices 默认使用的是前者,我们可以通过其 tokenRepository 属性来指定使用的 PersistentTokenRepository。这例子用JdbcTokenRepositoryImpl来进行持久化保存,显然要往数据库保存数据,肯定要有一张表,这个表security也有提供,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)。在数据库中创建该表即可。

创建后的表为:

Spring Security教程(七)_第1张图片

所以持久化方式配置只需要将第一种方式的TokenBasedRememberMeServices进行修改就可以,用以下代码提换就可以了:


		
		
		
		
		
         
            
            
            
            
         
      
	

三 两种配置的效果

Spring Security教程(七)_第2张图片

从上面的图可以看出,但没点击2周不用登陆的时候,登陆后再退出,再访问资源的时候就要求重新登陆。同时数据库也不会新增数据。



从上图可以看到,当勾选2周不用登陆在登陆后,就算退出登陆后,再访问资源也可以不用直接访问,同时,数据库也会将登陆信息保存起来,比较两次数据还可以发现,除了用户名没变,其他的数据都会因为第二次访问而进行更新。

你可能感兴趣的:(spring,security)