前言

  此框架由小菜独立开发,并且已经在生产环境中运行大约一年时间。

  也就是说,Security 框架写出来有一段时间了,但是一直没有公布、开源,经过不断迭代完善,终于算是拿得出手啦~

  Security 框架存在的意义并不是为了替代 Shiro 或 Spring Security ,而且提供另一种选择。

  当读者因为现有安全框架的复杂繁琐而苦恼时,为什么不尝试一下 Security 呢?

  请原谅小菜在本文直接照搬 GitHub 的 README,以后小菜会陆续完善使用教程和相关 Demo ,敬请关注~

  最后希望读者能给出宝贵意见、及时反馈问题,来帮助小菜继续完善框架。

README

简介

  本框架基于Spring MVC开发,是一款轻量级的安全认证框架。

  抛弃ShiroSpring Security等安全框架繁琐的配置,改为注解实现权限管理,配合Spring MVCRequestMapping注解,完美实现细粒度的权限控制。

  本框架以Redis作为持久化数据库,Ehcache作为内存级缓存,满足高性能需求。

  本框架删繁就简,以角色作为权限认证的唯一标准,并非传统的RBAC权限模型,在这里没有权限的概念,只有角色,角色就是权限,权限就是角色,因此本框架适合应用于互联网项目,尤其适合前后端分离模式下的后端接口。

特性

  • 高性能(设计简洁、内置缓存)
  • 基于注解
  • 安全的密码加密机制
  • 灵活的配置项
  • 易于集成、扩展
  • Session共享
  • 分布式部署
  • 实现匿名认证基础的登陆认证基于角色的权限管理基于范围表达式的权限管理HTTP Basic Authentication
  • 并发登录控制
  • 基础的在线会话管理
  • 验证码框架封装
  • 第三方登录集成

主要依赖

  • Spring MVC,基础依赖
  • Httpclient,第三方登陆依赖
  • FastJson,序列化依赖
  • Ehcache,缓存依赖
  • Redis,持久化依赖

集成

添加Maven项目依赖

<!-- security frame work -->
<dependency>
<groupId>org.yangyuan</groupId>
<artifactId>security</artifactId>
<version>0.0.1</version>
</dependency>

与Spring MVC集成

<!-- 扫描spring注解 -->
<context:component-scan base-package="com.yourself, org.yangyuan.security" />
<!-- 身份认证拦截器 -->
<mvc:interceptors>
<bean class="org.yangyuan.security.servlet.SecurityInterceptor"></bean>
</mvc:interceptors>

添加配置文件

  将本项目中的security.properties文件拷贝到真实项目resources根目录下,与log4j.properties位置相同,即保证编译后这个文件在classes目录下。

security.properties说明

#Session有效期
#这是一个相对值,相对于用户最后一次访问的时间
#也就是说,只有当用户超过此时间不活跃,Session才会失效
#单位秒(s)
session.expiresMilliseconds=2592000000
#是否启用Session垃圾回收器
session.gc.open=true
#Session垃圾回收器Lua脚本
session.gc.script=for i=48,83,1 do local partition if(i > 57) then partition = string.char(i + 39) else partition = string.char(i) end local setkey = 'security:session:set:'..partition local principals = redis.call('ZRANGEBYSCORE', setkey, '-inf', ARGV[1]) redis.call('ZREMRANGEBYSCORE', setkey, '-inf', ARGV[1]) if(principals and (table.maxn(principals) > 0)) then for ii,vv in ipairs(principals) do local hashkey = 'security:session:hash:'..partition redis.call('HDEL', hashkey, vv) end end end
#Session垃圾回收器执行时间间隔
#单位秒(s)
session.gc.gcDelaySecond=86400 #cookie名称
cookie.name=sid
#cookie域名
cookie.domain=.cospace.xyz
#cookie路径
cookie.path=/
#此配置为true时,cookie无法通过js脚本操作
cookie.http_only=true
#是否启用HTTPS
cookie.secure=true
#cookie有效期,一般不需要改动,目前设置的是最大值,相当于永不过期
#因为cookie的生命周期由服务器端维护,所以客户端不需要关心过期时间
cookie.max_age=315360000 #Redis客户端连接工厂
#负责提供Redis客户端连接
common.redisResourceFactory=cc.cospace.web.security.dao.DefaultRedisResourceFactory #安全管理器实现
core.securityManager=org.yangyuan.security.core.DefaultSecurityManager
#安全唯一标识生成器实现
core.principalFactory=org.yangyuan.security.core.DefaultPrincipalFactory
#缓存管理器实现
core.cacheManager=org.yangyuan.security.core.DefaultCacheManager
#是否复用客户端subject
#如果设为true,客户端登陆时如果携带有subject信息,那么复用此subject,不再创建新的subject
#如果设为false,则登录时忽略客户端携带的subject信息,总是创建新的subject
core.useClientSubjectLogin=false
#并发主题控制器
#[org.yangyuan.security.core.MultiportConcurrentSubjectControl]允许同一个账号同时在不同客户端登陆
#[org.yangyuan.security.core.SingleConcurrentSubjectControl]同一个账号同一时刻只能在一个客户端登陆,如果之前在其他客户端登陆过,那么之前的登陆将失效
#[org.yangyuan.security.core.RefuseConcurrentSubjectControl]同一个账号同一时刻只能在一个客户端登陆,如果之前在其他客户端登陆过,那么本次登陆将会失败,除非其他客户端主动退出登陆
core.concurrentSubjectControl=org.yangyuan.security.core.MultiportConcurrentSubjectControl
#认证回调
#此处理器用来响应认证结果(成功、失败、拒绝访问)
#具体的响应依赖于具体的业务,框架只负责通知认证结果
core.securityAuthHandler=cc.cospace.web.security.core.DefaultSecurityAuthHandler #ehcache缓存数据访问层(缓存层)
dao.ehcacheSessionDao=org.yangyuan.security.dao.EhcacheSessionDao
#redis数据访问层(持久化层)
dao.redisSessionDao=org.yangyuan.security.dao.RedisSessionDao
#持久化数据源(用户名密码模式)
dao.jdbcRealm=org.yangyuan.security.realm.jdbc.JdbcRealm
#第三方数据源
dao.remoteRealm=org.yangyuan.security.realm.remote.RemoteRealm
#本地认证数据访问层(用户名密码模式)
dao.jdbcSessionDao=org.yangyuan.security.dao.JdbcSessionDao
#第三方登录认证数据访问层
dao.remoteSessionDao=org.yangyuan.security.dao.RemoteSessionDao
#用户名密码模式登录适配器
#此适配器实现安全认证与具体项目用户数据存储之间的解耦
dao.jdbcRealmAdaptor=userService
#第三方登录适配器
#此适配器实现安全认证与具体项目用户数据存储之间的解耦
dao.remoteRealmAdaptor=userService #cache在内存中最多可以存放的元素的数量。
#0表示没有限制。
#如果放入cache中的元素超过这个数值,有两种可能:
#1、若overflowToDisk的属性值为true,会将cache中多出的元素放入磁盘文件中。
#2、若overflowToDisk的属性值为false,会根据memoryStoreEvictionPolicy的策略替换cache中原有的元素。
cache.maxElementsInMemory=10000
#缓存是否永驻内存。
#如果值是true,cache中的元素将一直保存在内存中,不会因为时间超时而丢失。
#因此在这个值为true的时候,timeToIdleSeconds和timeToLiveSeconds两个属性的值就不起作用了。
cache.eternal=false
#内存中的元素数量溢出是否写入磁盘。
#系统会根据标签<diskStore path="java.io.tmpdir"/>中path的值查找对应的属性值。
#如果系统的java.io.tmpdir的值是/temp,写入磁盘的文件就会放在这个文件夹下,文件的名称是cache的名称,后缀名为data。
cache.overflowToDisk=false
#是否持久化内存中的缓存到磁盘。
#当这个属性的值为true时,系统在初始化的时候会在磁盘中查找文件名为cache名称,后缀名为index的的文件,如CACHE_FUNC.index。
#这个文件中存放了已经持久化在磁盘中的cache的index,找到后把cache加载到内存。
cache.diskPersistent=false
#访问cache中元素的最大间隔时间。
#如果超过此时间cache中的某个元素没有任何访问,那么这个元素将被从cache中清除。
cache.timeToIdleSeconds=900
#cache中元素的总生存时间,cache中的某个元素从创建到消亡的时间。
#从创建开始计时,当超过这个时间,这个元素将被从cache中清除,即便是这个元素被频繁访问。
cache.timeToLiveSeconds=7200
#内存存储与释放清理策略
#LRU最近最少使用
#LFU历史访问频率最低
#FIFO先进先出
cache.memoryStoreEvictionPolicy=LRU #普通验证码有效期
#单位s
captcha.normal.expireSecond=900
#普通验证码多次发送最短时间间隔
#单位s
captcha.normal.minIntervalSecond=50
#图形验证码有效期
#单位s
captcha.image.expireSecond=600
#图形验证码错误统计周期
#单位s
captcha.image.wrongPeriodSecond=60
#图形验证码统计周期内允许最大错误次数
captcha.image.periodMaxWrongCount=3

具体业务类实现

  • common.redisResourceFactory,为框架提供Redis连接,实现RedisResourceFactory接口。
  • core.securityAuthHandler,自定义认证结果行为,用来处理认证成功、未登录、权限不足的具体业务,实现SecurityAuthHandler接口。
  • dao.jdbcRealmAdaptor,提供用户名/密码登陆模式必要的数据,具体出参入参参考源码注释,实现JdbcRealmAdaptor接口。
  • dao.remoteRealmAdaptor,提供第三方登陆模式必要的数据,具体出参入参参考源码注释,实现RemoteRealmAdaptor接口。

  security.properties文件中配置的所有类型,可以配置成完整类名(包名+类名),也可以配置成spring IOC中的Bean名称,根据业务情况自由选择。

  一般来讲,除非需要自己扩展框架,否则只需要实现具体业务类,然后修改一下cookie相关配置即可,其他配置项均可使用默认配置。

验证码模块使用介绍

  验证码模块只实现了公共逻辑,并没有实现具体的发送逻辑,目的是留给使用者更多的操作空间,使得框架具有更强的适应性。

  如果需要使用验证码模块,最佳实践如下:

  • 如果需要使用手机短信邮箱邮件验证码,则定义一个抽象类,假设名称为AbstractPhoneEmailSecurityCaptchaService,继承模块中的AbstractPhoneEmailSecurityCaptcha,实现newCodesendToPhonesendToEmail方法,这三个方法是公共方法,但必须交给使用者实现,因为不同的项目发送短信、邮件的方式不尽相同,生成验证码的规则也不尽相同。然后在项目中以AbstractPhoneEmailSecurityCaptchaService为基础,派生出具体的业务类,比如发送注册验证码的业务类RegisterCaptchaService,继承AbstractPhoneEmailSecurityCaptchaService,然后实现nametitlecontent方法即可。
  • 如果需要使用图形验证码,则定义一个抽象类,假设名称为AbstractSecurityImageCaptchaService,继承模块中的AbstractSecurityImageCaptcha,实现newCode方法,生成的验证码取决于实际项目中图形生成器的能力,避免生成无法被图形生成器识别的字符,当然,图形生成器您自己实现,看着办。然后在项目中以AbstractSecurityImageCaptchaService为基础,派生出具体的业务类,比如登陆图形验证码的业务类LoginImageCaptchaService,继承AbstractSecurityImageCaptchaService,然后实现name方法即可。

  通过以上描述可以看出,验证码模块只是封装了繁琐的验证码发送标记、验证等操作,并不干预具体的发送实现。

  使用者封装好适合自己的抽象基类后,不论任何业务,只需要继承抽象基类即可轻松实现,并天然实现业务之间的隔离。

  总结一下,使用者只需要关注发送手机短信发送邮件生成验证码文本生成验证码图片具体实现,然后根据具体业务设定好验证码标题验证码内容业务名称(用来隔离业务)即可。

使用

  经过前期配置之后,使用就非常简单了!

  只需要在Controller层使用Security注解即可,Security注解具体使用方法请参考源码注释。

  本框架只关注角色认证,而不关注角色的存储、定义,彻底实现安全认证框架与实际项目之间的解耦。

  在定义角色名称时,不应该出现框架已经占用的关键字,包括:[]{}><,:,否则会引起冲突。

GitHub 项目地址

Security

Security - 轻量级Java身份认证、访问控制安全框架的更多相关文章

  1. ASP.NET Core的身份认证框架IdentityServer4--(3)令牌服务配置访问控制跟UI添加

    使用密码保护API OAuth 2.0 资源所有者密码授权允许一个客户端发送用户名和密码到IdentityServer并获得一个表示该用户的可以用于访问api的Token. 该规范建议仅对" ...

  2. 最简单易懂的Spring Security 身份认证流程讲解

    最简单易懂的Spring Security 身份认证流程讲解 导言 相信大伙对Spring Security这个框架又爱又恨,爱它的强大,恨它的繁琐,其实这是一个误区,Spring Security确 ...

  3. ASP.NET Core的身份认证框架IdentityServer4--入门

    ASP.NET Core的身份认证框架IdentityServer4--入门 2018年08月11日 10:09:00 qq_42606051 阅读数 4002   https://blog.csdn ...

  4. Spring Security构建Rest服务-1203-Spring Security OAuth开发APP认证框架之短信验证码登录

    浏览器模式下验证码存储策略 浏览器模式下,生成的短信验证码或者图形验证码是存在session里的,用户接收到验证码后携带过来做校验. APP模式下验证码存储策略 在app场景下里是没有cookie信息 ...

  5. Smart Framework:轻量级 Java Web 框架

    Smart Framework:轻量级 Java Web 框架 收藏 黄勇   工作闲暇之余,我开发了一款轻量级 Java Web 框架 —— Smart Framework. 开发该框架是为了: 加 ...

  6. ASP.NET Core的无状态身份认证框架IdentityServer4

    Identity Server 4是IdentityServer的最新版本,它是流行的OpenID Connect和OAuth Framework for .NET,为ASP.NET Core和.NE ...

  7. cache4j轻量级java内存缓存框架,实现FIFO、LRU、TwoQueues缓存模型

    简介 cache4j是一款轻量级java内存缓存框架,实现FIFO.LRU.TwoQueues缓存模型,使用非常方便. cache4j为java开发者提供一种更加轻便的内存缓存方案,杀鸡焉用EhCac ...

  8. 初识轻量级Java开源框架 --- Spring

    初识轻量级Java开源框架 --- Spring 作者:egg 微博:http://weibo.com/xtfggef 出处:http://blog.csdn.net/zhangerqing spri ...

  9. [转]轻量级 Java Web 框架架构设计

    工作闲暇之余,我想设计并开发一款轻量级 Java Web 框架,看看能否取代目前最为流行的而又越来越重的 Spring.Hibernate 等框架.请原谅在下的大胆行为与不自量力,本人不是为了重造轮子 ...

随机推荐

  1. Mysql创建索引

    1.索引作用 在索引列上,除了上面提到的有序查找之外,数据库利用各种各样的快速定位技术,能够大大提高查询效率.特别是当数据量非常大,查询涉及多个表时,使用索引往往能使查询速度加快成千上万倍. 例如,有 ...

  2. Copy List with Random Pointer(复杂链表复制)

    输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否则判题程序 ...

  3. JAVA 创建对象4种方法

    java创建对象的几种方式 博客分类: java   (1) 用new语句创建对象,这是最常见的创建对象的方法.(2) 运用反射手段,调用java.lang.Class或者java.lang.refl ...

  4. 多重影分身——C#中多线程的使用二(争抢共享资源)

    只要服务器承受得了,我们可以开任意个线程同时工作以提高效率,然而 两个线程争抢资源可能导致数据混乱. 例如: public class MyFood { public static int Last ...

  5. saltstack安装部署以及简单实用

    一,saltstack简介:     SaltStack是一种新的基础设施管理方法开发软件,简单易部署,可伸缩的足以管理成千上万的服务器,和足够快的速度控制,与他们交流,以毫秒为单位. SaltSta ...

  6. 中文字体名称对照表(unicode码)及20个web安全字体

    在Web编码中,CSS默认应用的Web字体是有限的,虽然在新版本的CSS3,我们可以通过新增的@font-face属性来引入特殊的浏览器加载字体.但多数情况下,考虑各个因素的影响我们还是在尽量充分利用 ...

  7. XYC2016上半年工作笔记整理

    只要团队在,做那个方向都可能 这个产品的用户群人均价值高 第一次产品介绍会议就介绍了产品的初期全部目标功能 传统互联网人的产品思路比较偏媒体内容服务特性. 产品转化率高说明了其发展势头 任何一个形式变 ...

  8. Nginx负载均衡和反向代理

    1:反向代理 代理就是中介,那有反向代理就有正向代理,两者的区别是什么嘞? 正向代理隐藏真实客户端,服务端不知道实际发起请求的客户端.,proxy和client同属一个LAN,对server透明: 反 ...

  9. Cocos2d-x 实战

    跨平台商业项目实战:攻城大作战游戏创意触发点:做什么样的游戏?分析当前主流的游戏:经典游戏(俄罗斯方块).大众化的游戏(卡牌游戏.休闲游戏).重口味游戏. 游戏创意:生活当中 游戏开发流程:1.策划方 ...

  10. nfs 、ftp 和samba都有什么区别?

    NFS:Network File System 是已故的Sun公司制定的用于分布式访问的文件系统,它的本质是文件系统.主要在Unix系列操作系统上使用,基于TCP/IP协议层,可以将远程的计算机磁盘挂 ...