前言java
此框架由小菜獨立開發,而且已經在生產環境中運行大約一年時間。git
也就是說,Security 框架寫出來有一段時間了,可是一直沒有公佈、開源,通過不斷迭代完善,終於算是拿得出手啦~github
Security 框架存在的意義並非爲了替代 Shiro 或 Spring Security ,並且提供另外一種選擇。web
當讀者由於現有安全框架的複雜繁瑣而苦惱時,爲何不嘗試一下 Security 呢?
redis
請原諒小菜在本文直接照搬 GitHub 的 README,之後小菜會陸續完善使用教程和相關 Demo ,敬請關注~spring
最後但願讀者能給出寶貴意見、及時反饋問題,來幫助小菜繼續完善框架。數據庫
README後端
本框架基於Spring MVC
開發,是一款輕量級的安全認證框架。緩存
拋棄Shiro
、Spring Security
等安全框架繁瑣的配置,改成註解實現權限管理,配合Spring MVC
的RequestMapping
註解,完美實現細粒度的權限控制。安全
本框架以Redis
做爲持久化數據庫,Ehcache
做爲內存級緩存,知足高性能需求。
本框架刪繁就簡,以角色做爲權限認證的惟一標準,並不是傳統的RBAC
權限模型,在這裏沒有權限的概念,只有角色,角色就是權限,權限就是角色,所以本框架適合應用於互聯網項目,尤爲適合先後端分離模式下的後端接口。
添加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中的元素超過這個數值,有兩種可能: #一、若overflowToDisk的屬性值爲true,會將cache中多出的元素放入磁盤文件中。 #二、若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
具體業務類實現
RedisResourceFactory
接口。SecurityAuthHandler
接口。JdbcRealmAdaptor
接口。RemoteRealmAdaptor
接口。 security.properties
文件中配置的全部類型,能夠配置成完整類名(包名+類名),也能夠配置成spring IOC
中的Bean
名稱,根據業務狀況自由選擇。
通常來說,除非須要本身擴展框架,不然只須要實現具體業務類,而後修改一下cookie相關配置便可,其餘配置項都可使用默認配置。
驗證碼模塊使用介紹
驗證碼模塊只實現了公共邏輯,並無實現具體的發送邏輯,目的是留給使用者更多的操做空間,使得框架具備更強的適應性。
若是須要使用驗證碼模塊,最佳實踐以下:
AbstractPhoneEmailSecurityCaptchaService
,繼承模塊中的AbstractPhoneEmailSecurityCaptcha
,實現newCode
、sendToPhone
、sendToEmail
方法,這三個方法是公共方法,但必須交給使用者實現,由於不一樣的項目發送短信、郵件的方式不盡相同,生成驗證碼的規則也不盡相同。而後在項目中以AbstractPhoneEmailSecurityCaptchaService
爲基礎,派生出具體的業務類,好比發送註冊驗證碼的業務類RegisterCaptchaService
,繼承AbstractPhoneEmailSecurityCaptchaService
,而後實現name
、title
、content
方法便可。AbstractSecurityImageCaptchaService
,繼承模塊中的AbstractSecurityImageCaptcha
,實現newCode
方法,生成的驗證碼取決於實際項目中圖形生成器的能力,避免生成沒法被圖形生成器識別的字符,固然,圖形生成器您本身實現,看着辦。而後在項目中以AbstractSecurityImageCaptchaService
爲基礎,派生出具體的業務類,好比登錄圖形驗證碼的業務類LoginImageCaptchaService
,繼承AbstractSecurityImageCaptchaService
,而後實現name
方法便可。經過以上描述能夠看出,驗證碼模塊只是封裝了繁瑣的驗證碼發送標記、驗證等操做,並不干預具體的發送實現。
使用者封裝好適合本身的抽象基類後,不論任何業務,只須要繼承抽象基類便可輕鬆實現,並自然實現業務之間的隔離。
總結一下,使用者只須要關注發送手機短信、發送郵件、生成驗證碼文本、生成驗證碼圖片具體實現,而後根據具體業務設定好驗證碼標題、驗證碼內容、業務名稱(用來隔離業務)便可。
通過前期配置以後,使用就很是簡單了!
只須要在Controller
層使用Security
註解便可,Security
註解具體使用方法請參考源碼註釋。
本框架只關注角色認證,而不關注角色的存儲、定義,完全實現安全認證框架與實際項目之間的解耦。
在定義角色名稱時,不該該出現框架已經佔用的關鍵字,包括:[
、]
、{
、}
、>
、<
、,
、:
,不然會引發衝突。
GitHub 項目地址