首页 > 其他分享 >Spring Security(6)

Spring Security(6)

时间:2022-11-27 23:01:41浏览次数:41  
标签:return Spring class token PersistentRememberMeToken series Security public

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


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

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

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

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

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

Spring Security(6)_Spring Security


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

/**
* MongoDaoSupport
*
* @author 湘王
*/
@Component
public class MongoDaoSupport<T> {
@Autowired
private MongoTemplate mongoTemplate;

// 插入数据
public boolean insert(PersistentRememberMeToken token) {
if (Objects.isNull(token)) {
return false;
}

Object object = mongoTemplate.save(token);
if (Objects.nonNull(object)) {
return true;
}

return false;
}
}


然后再在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注解注入):

Spring Security(6)_Spring Security_02


运行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值。


访问数据记录:

Spring Security(6)_Java_03


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





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


标签:return,Spring,class,token,PersistentRememberMeToken,series,Security,public
From: https://blog.51cto.com/u_15817148/5890454

相关文章

  • Spring Security(6)
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ Spring Security使用MySQL保存cookie记录虽然方便,但是目前更多的主流互联网应用都是用NoSQL来保存非业务数据的,Spring......
  • springboot的基本使用
    SpringBoot简介SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程。使用了Spring框架后已经简化了我们的开发,而SpringBoot......
  • 第2-4-6章 springboot整合规则引擎Drools-业务规则管理系统-组件化-中台
    目录7.Spring整合Drools7.1Spring简单整合Drools7.1.1以上代码均在drools_spring项目中7.2Spring整合Drools+web7.2以上代码均在drools_springweb项目中7.3SpringBo......
  • 一文带你了解 Spring 的@Enablexxx 注解
    layout:postcategories:Javatitle:一文带你了解Spring的@Enablexxx注解tagline:by子悠tags:-子悠前面的文章给大家介绍Spring的重试机制的时候有提到......
  • springBoot mybatis-plus mySql代码生成器
    一、用到的依赖参考官网<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/X......
  • SpringBoot面试题
    1SpringBoot启动Tomcat1.1Spring在启动时创建一个Spring容器1.2利用@ConditionalOnClass技术判断classpath中是否存丰Tomcat依赖,如果存在则生成一个启动Tomcat的Bean1.......
  • Spring Cloud 最新版发布,Spring Security + OAuth2 终于安排上了!
    大家好,我是栈长。今天给大家通报一则框架更新消息,时隔两个月,SpringCloud2021.0.5最新版发布了,来看下最新的SpringCloud版本情况:SpringCloud无疑是现在Java微服务......
  • Spring Boot笔记(全)
    前言serverlet服务器端小程序,第一代javaweb开发技术,基于java实现了一套用于动态网站的APITomcat\Jetty\Undertow都是Servelet容器,用来管理Servelet类jsp在html页......
  • Grafana+OpenSearch+Spring Boot集成(三) 【Grafana警报】
    上一篇:Grafana+OpenSearch+SpringBoot集成(二)【Grafana使用】在数据可视化中,可能会存在监测某项数据是否会超过一定数值的需求。Grafana提供了自动告警功能,可以通过配......
  • Java基础_Spring三种构造方法
    第一种构造方法接口:FirstDaopackagecom.leehl.springgitider.dao;publicinterfaceFirstDao{publicvoidsave();}主方法:FirstDaoimplpacka......