首页IT科技springsecurity6 中文文档(Spring Security(6))

springsecurity6 中文文档(Spring Security(6))

时间2025-06-14 02:14:42分类IT科技浏览4882
导读:您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~...

您好          ,我是湘王                  ,这是我的博客园      ,欢迎您来       ,欢迎您再来~

SpringSecurity使用MySQL保存cookie记录虽然方便                  ,但是目前更多的主流互联网应用都是用NoSQL来保存非业务数据的         ,Spring Security也应该可以实现这个功能          。之前SpringSecurity官方并不支持使用NoSQL来保存cookie    ,但这个问题对于一个爱钻研的码农来说应该只是个小CASE——毕竟只要有代码                 ,就没有搞不定的问题——JdbcTokenRepositoryImpl的启发            ,查看其源码  ,可以发现JdbcDaoSupport只是用来提供数据源                ,无实际意义               ,PersistentTokenRepository才是要实现的接口                  。

JdbcTokenRepositoryImpl的源码非常简单,看懂了就能照着写出Mongo的实现      。题外话:阅读源码是个能够很快提高开发能力的捷径             ,如Spring框架            、Spark源码等等       。

下面就来开始咱们的NoSQL改造DIY                  。

首先安装并运行mongodb(我用的是mongodb-4.2.6)                  ,可以是虚拟机   ,也可以是Docker         。

再修改项目的pom.xml文件          ,增加mongodb依赖:

通过模仿JdbcDaoSupport                  ,来自定义自己的MongoDaoSupport:

然后再在MongoDaoSupport中增加两个重要的方法      ,让它支持Mongodb:

// 查询数据 public PersistentRememberMeToken getTokenBySeries(String series) { // // 如果是通过字符串方式诸葛插入字段值       ,那么通过mongoTemplate.findOne()得到的就是一个LinkedHashMap // LinkedHashMap<String, String> map = (LinkedHashMap<String, String>) mongoTemplate // .findOne(query, Object.class, "collectionName"); // return new PersistentRememberMeToken(map.get("username"), map.get("series"), // map.get("tokenValue"), DateUtils.format()map.get("date")); Query query = new Query(Criteria.where("series").is(series)); // // 这里原路返回PersistentRememberMeToken对象                  ,不会是LinkedHashMap // Object object = mongoTemplate.findOne(query, PersistentRememberMeToken.class); // return (PersistentRememberMeToken) obejct; return mongoTemplate.findOne(query, PersistentRememberMeToken.class); } // 更新数据 public boolean updateToken(String series, String tokenValue, Date lastUsed) { Query query = new Query(Criteria.where("series").is(series)); Update update = new Update(); update.set("tokenValue", tokenValue); update.set("date", lastUsed); // // 这里不能用DateUtils.parse(new Date())         ,否则getTokenBySeries()方法会抛出非法参数异常 // update.set("date", DateUtils.parse(new Date())); Object object = mongoTemplate.updateMulti(query, update, PersistentRememberMeToken.class); if (Objects.nonNull(object)) { return true; } return false; }

然后再定义MongoTokenRepositoryImpl:

/** * 自定义实现token持久化到mongodb * * @author 湘王 */ public class MongoTokenRepositoryImpl implements PersistentTokenRepository { @Autowired private MongoDaoSupport<PersistentRememberMeToken> mongoDaoSupport; @Override public void createNewToken(PersistentRememberMeToken token) { mongoDaoSupport.insert(token); } @Override public void updateToken(String series, String tokenValue, Date lastUsed) { mongoDaoSupport.updateToken(series, tokenValue, lastUsed); } @Override public PersistentRememberMeToken getTokenForSeries(String series) { return mongoDaoSupport.getTokenBySeries(series); } @Override public void removeUserTokens(String username) { } }

接着在WebSecurityConfiguration中用自定义的MongoTokenRepositoryImpl代替JdbcTokenRepositoryImpl:

// NoSQL方式实现记住我 @Bean public PersistentTokenRepository persistentTokenRepository() { // 自定义mongo方式实现 MongoTokenRepositoryImpl mongoTokenRepository = new MongoTokenRepositoryImpl(); return mongoTokenRepository; }

或者就直接(需要通过@Service注解注入):

运行postman测试    ,可以看到通过MongoDB实现了对cookie信息的存储与修改    。

如果mongodb中多出了_class字段                 ,可以加上额外的配置:

/** * 去除_class字段 * * @author 湘王 */ @Configuration public class MongoConfiguration implements InitializingBean { @Autowired @Lazy private MappingMongoConverter mappingMongoConverter; @Override public void afterPropertiesSet() { mappingMongoConverter .setTypeMapper(new DefaultMongoTypeMapper(null)); } }

多次运行可发现访问记录值的规律:

1                、同一用户会有多条访问记录

如果每次都明确执行login方法            ,那么每次都会产生不同的记录  ,否则只会更新同一条记录的tokenValue和date值;

token有效且未执行login方法                ,那么将更新最后一次产生的记录的tokenValue和date值                 。

2      、这说明token条数是与login方法执行次数一一对应的;

3         、只要token不失效               ,仅更新同一条记录series的token值            。

访问数据记录:

不管是Mongodb还是别的NoSQL,比如Redis             ,原理都是一样的  。

感谢您的大驾光临!咨询技术                、产品         、运营和管理相关问题                  ,请关注后留言                。欢迎骚扰   ,不胜荣幸~

声明:本站所有文章          ,如无特殊说明或标注                  ,均为本站原创发布               。任何个人或组织      ,在未征得本站同意时       ,禁止复制      、盗用                、采集           、发布本站内容到任何网站   、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益                  ,可联系我们进行处理             。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
网站设计的通用设计系统(为什么每个网站都应该采用一个通用的设计系统?) 关键词seo排名如何(掌握SEO关键词快速排名前三位的秘诀)