Spring-Security (学习记录六)--采用ehcache缓存UserDetails
1. spring-security提供了缓存UserDetails的UserDetailsService实现类。
- Spring Security提供了一个实现了可以缓存UserDetails的UserDetailsService实现类,CachingUserDetailsService。该类的构造接收一个用于真正加载UserDetails的UserDetailsService实现类。当需要加载UserDetails时,其首先会从缓存中获取,如果缓存中没有对应的UserDetails存在,则使用持有的UserDetailsService实现类进行加载,然后将加载后的结果存放在缓存中。UserDetails与缓存的交互是通过UserCache接口来实现的。CachingUserDetailsService默认拥有UserCache的一个空实现引用,NullUserCache。以下是CachingUserDetailsService的类定义。
public class CachingUserDetailsService implements UserDetailsService {
private UserCache userCache = new NullUserCache();
private final UserDetailsService delegate;
CachingUserDetailsService(UserDetailsService delegate) {
this.delegate = delegate;
}
public UserCache getUserCache() {
return userCache;
}
public void setUserCache(UserCache userCache) {
this.userCache = userCache;
}
public UserDetails loadUserByUsername(String username) {
UserDetails user = userCache.getUserFromCache(username);
if (user == null) {
user = delegate.loadUserByUsername(username);
}
Assert.notNull(user, "UserDetailsService " + delegate + " returned null for username " + username + ". " +
"This is an interface contract violation");
userCache.putUserInCache(user);
return user;
}
}
- 我们可以看到当缓存中不存在对应的UserDetails时将使用引用的UserDetailsService类型的delegate进行加载。加载后再把它存放到Cache中并进行返回。除了NullUserCache之外,Spring Security还为我们提供了一个基于Ehcache的UserCache实现类,EhCacheBasedUserCache,其源码如下所示。
public class EhCacheBasedUserCache implements UserCache, InitializingBean {
private static final Log logger = LogFactory.getLog(EhCacheBasedUserCache.class);
private Ehcache cache;
public void afterPropertiesSet() throws Exception {
Assert.notNull(cache, "cache mandatory");
}
public Ehcache getCache() {
returncache;
}
public UserDetails getUserFromCache(String username) {
Element element = cache.get(username);
if (logger.isDebugEnabled()) {
logger.debug("Cache hit: " + (element != null) + "; username: " + username);
}
if (element == null) {
returnnull;
} else {
return (UserDetails) element.getValue();
}
}
public void putUserInCache(UserDetails user) {
Element element = new Element(user.getUsername(), user);
if (logger.isDebugEnabled()) {
logger.debug("Cache put: " + element.getKey());
}
cache.put(element);
}
public void removeUserFromCache(UserDetails user) {
if (logger.isDebugEnabled()) {
logger.debug("Cache remove: " + user.getUsername());
}
this.removeUserFromCache(user.getUsername());
}
public void removeUserFromCache(String username) {
cache.remove(username);
}
public void setCache(Ehcache cache) {
this.cache = cache;
}
}
2. 通过配置来完成缓存 UserDetails (使用ehcache)
- 从上述源码我们可以看到EhCacheBasedUserCache所引用的Ehcache是空的,所以,当我们需要对UserDetails进行缓存时,我们只需要定义一个Ehcache实例,然后把它注入给EhCacheBasedUserCache就可以了。接下来我们来看一下定义一个支持缓存UserDetails的CachingUserDetailsService的示例。
<!-- 认证管理器,配置了管理员与角色的关系 -->
<security:authentication-manager alias="authenticationManager">
<!-- 配置账号密码所属的角色 角色以 ROLE_开头,为spring获取名称的标识 (xml方式的才需要)
user-service-ref="accountService" : 配置启动数据库方式获取用户和角色,xml失效
-->
<security:authentication-provider user-service-ref="cachingUserDetailsService">
<!-- 密码采用md5加密 -->
<security:password-encoder hash="md5" />
</security:authentication-provider>
</security:authentication-manager>
<bean id="cachingUserDetailsService" class="org.springframework.security.config.authentication.CachingUserDetailsService">
<!-- 真正加载UserDetails的UserDetailsService -->
<constructor-arg ref="accountService"/>
<!-- 缓存UserDetails的UserCache -->
<property name="userCache">
<bean class="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache">
<!-- 用于真正缓存的Ehcache对象 -->
<property name="cache" ref="ehcache4UserDetails"/>
</bean>
</property>
</bean>
<!-- 将使用默认的CacheManager创建一个名为ehcache4UserDetails的Ehcache对象 -->
<bean id="ehcache4UserDetails" class="org.springframework.cache.ehcache.EhCacheFactoryBean"/>
3. 引入ehcache
- pom.xml中引入
<!-- ehcache需要的依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
<!-- 加入ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.7.4</version>
</dependency>
添加ehcache.xml配置文件(详见附件)
项目中添加spring-ehcache.xml (详见附件)
<!-- 开启spring缓存 -->
<cache:annotation-driven cache-manager="cacheManager" />
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" p:shared="false" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="cacheManagerFactory" />
</beans>
这样。缓存UserDetails就成功了。
百度云链接:http://pan.baidu.com/s/1c2FmMQG 密码:vnov
Spring-Security (学习记录六)--采用ehcache缓存UserDetails的更多相关文章
- Spring Security 学习记录
一.核心拦截器详细说明 1.WebAsyncManagerIntegrationFilter 根据请求封装获取WebAsyncManager 从WebAsyncManager获取/注册Security ...
- [转]Spring Security学习总结一
[总结-含源码]Spring Security学习总结一(补命名空间配置) Posted on 2008-08-20 10:25 tangtb 阅读(43111) 评论(27) 编辑 收藏 所属分 ...
- [转]Spring Security学习总结二
原文链接: http://www.blogjava.net/redhatlinux/archive/2008/08/20/223148.html http://www.blogjava.net/red ...
- SpringBoot + Spring Security 学习笔记(三)实现图片验证码认证
整体实现逻辑 前端在登录页面时,自动从后台获取最新的验证码图片 服务器接收获取生成验证码请求,生成验证码和对应的图片,图片响应回前端,验证码保存一份到服务器的 session 中 前端用户登录时携带当 ...
- Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客
==他的博客应该不错,没有细看 Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客 http://blog.csdn.net/u012706811/article/det ...
- Spring security 学习 (自助者,天助之!)
自己努力,何必要强颜欢笑的求助别人呢? 手心向下不求人! Spring security学习有进展哦: 哈哈! 1.页面都是动态生产的吧! 2.设置权限: a:pom.xml配置jar包 b:cr ...
- SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能
在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...
- 我的Spring Boot学习记录(二):Tomcat Server以及Spring MVC的上下文问题
Spring Boot版本: 2.0.0.RELEASE 这里需要引入依赖 spring-boot-starter-web 这里有可能有个人的误解,请抱着怀疑态度看. 建议: 感觉自己也会被绕晕,所以 ...
- spring security 学习资料
spring security 学习资料 网址 Spring Security 文档参考手册中文版 https://springcloud.cc/spring-security.html
随机推荐
- 【leetcode】949. Largest Time for Given Digits
题目如下: Given an array of 4 digits, return the largest 24 hour time that can be made. The smallest 24 ...
- Vue学习笔记【6】——事件修饰符
.stop 阻止冒泡(阻止事件向外层冒泡) .prevent 阻止默认事件(链接跳转.表单提交) .capture 添加事件侦听器时使用事件捕获模式(从外到里触发事件) .self 只当事件在该元素本 ...
- 如何 修改jsp页面时间格式
先导入文件 <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> &l ...
- 【LeetCode 14】最长公共前缀
题目链接 [题解] 二分最长前缀的长度. 然后暴力把第2..n个字符串和第1个字符串的前mid个字符匹配. 还有一种比较厉害的算法. 把这n个字符串加入到字典树当中去. 然后根节点到第一个有分支的节点 ...
- Android中查看当前Activity是否销毁
进入到Android-sdk中platform-tools目录 在命令行中执行以下命令 adb shell dumpsys activity>activity.txt 可以将当前的四大组件(Ac ...
- NX二次开发-C语言文件读写fwrite和fread函数
NX9+VS2012 #include <uf.h> #include <stdio.h> UF_initialize(); /* //设置文件路径 const char* f ...
- 使用PHP和MySQL添加数据库时的小错误及注意事项总结
刚刚开始使用PHP和MySQL搭配着,从前端往数据库传数据,错误犯了不少,总结一下,提醒自己 1.写MySQL语句时,标点符号使用错 正确的应该是 $sql = "INSERT INTO ` ...
- (转)OpenFire源码学习之七:组(用户群)与花名册(用户好友)
转:http://blog.csdn.net/huwenfeng_2011/article/details/43413651 Group 在openfire中的gorop——组,也可以理解为共享组.什 ...
- ThinkPHP学习(二)理清ThinkPHP的目录结构及访问规则,创建第一个控制器
ThinkPHP的目录结构 回顾上一篇的安装目录: 目录对应关系 F:\\PHP├─index.php 入口文件├─README.md README文件├─Applicatio ...
- 数据可视化(Echart) :柱状图、折线图、饼图等六种基本图表的特点及适用场合
数据可视化(Echart) 柱状图.折线图.饼图等六种基本图表的特点及适用场合 参考网址 效果图 源码 <!DOCTYPE html> <html> <head> ...