1. 程式人生 > >Shiro Demo 示例(SpringMVC-Mybatis-Shiro-redis)

Shiro Demo 示例(SpringMVC-Mybatis-Shiro-redis)

sql ear 一半 之間 bootstra dir 示例 mon 升級

技術分享圖片




Shiro Demo 準備工作

運行前申明

  1. 請看完本頁面的所有細節,對你掌握這個項目來說很重要,別一上來就搞,你不爽,我也不爽。
  2. 本項目需要一定的Java功底,需要對SpringMvcMybatis,有基本的了解,其次對Redis有了解和使用更佳。
  3. 本項目理論上,只需要一個Redis,然後一個Mysql和一個有Maven環境的開發工具即可運行起來。
  4. 對Reids沒有了解,請看這裏:對Redis的理解,Redis是什麽,Redis和Memcache誰快?。

運行步驟

  1. 從 Github 下載源碼(不定期更新和修復BUG),導入到Eclipse
    MyEclipesIdea類似開發工具。
  2. 解決編譯錯誤,修改JDK1.7以上(請勿使用工具自帶JDK)。
  3. Mysql數據庫中創建一個數據庫,庫名隨便。
  4. 從項目/init/sql/下,先執行tables.sql創建表,再運行init.data.sql插入初始化數據。
  5. 再修改配置jdbc.properties把數據庫鏈接改成您的。
  6. 安裝Redis服務,如果您沒用過,或者沒安裝,請看這裏==>Redis 安裝,以及註意事項都在裏面有說明。Redis啟動報錯請看這裏:Please see the documentation included with the binary distributions for more details on the --maxheap flag.
  7. 安裝完畢後,修改配置:spring-cache.xml,如果是本地,無序修改,啟動Redis,如對Redis不了解的同學,建議別設置密碼。
  8. 運行項目,如果還有錯誤請參考異常信息,並解決,如果實在不能解決,請加QQ群交流,群需要付費5元,加群請看右側菜單。
  9. 項目帳號和線上Demo一致:管理員帳號:admin,密碼:sojson.com 如果密碼錯誤,請用 sojson

線上Demo說明

  1. Demo已經部署到線上,地址是:http://shiro.itboy.net
  2. 管理員帳號:admin,密碼:sojson.com 如果密碼錯誤,請用 sojson
  3. 你可以註冊自己的帳號,然後用管理員賦權限給你自己的帳號,但是,每20分鐘會把數據初始化一次。建議自己下載源碼,讓Demo跑起來,然後跑的更快,有問題加群解決。

Shiro Demo 源碼下載

Shiro Demo 非Maven項目依賴包下載:點我下載

Github 0.1版本下載:https://github.com/baichengzhou/SpringMVC-Mybatis-shiro,(請下載0.2版本)

Github 0.2版本下載:https://github.com/baichengzhou/SpringMVC-Mybatis-Shiro-redis-0.2

Shiro Demo 0.2版本介紹:https://www.sojson.com/blog/165.html

Shiro Demo 0.2版本主要解決的問題為0.1版本出現的問題和BUG。

Shiro Demo 0.2版本為Shiro Demo 0.1的升級版本

PS:請選用0.2版本,這樣你遇到的問題會比較少。

升級內容:

  1. 修復了些許BUG,優化了語法。
  2. 0.1版本限制較多,比如要部署到Tomcat Root下才能正常運行,就是用http://localhost:8080方式訪問。
  3. 0.2版本可以采用目錄訪問,如:http://localhost:8080/shiro.demo/,默認項目名稱為/shiro.demo/

Shiro 簡介

Apache Shiro 是 Java 的一個安全框架。我們經常看到它被拿來和 Spring 的 Security 來對比。大部分人認為 Shiro 比 Security 要簡單。我的觀點贊成一半一半吧。

首先 Shiro 確實和 Security 是同類型的框架,主要用來做安全,也就是我們俗稱的權限校驗(控制)。居多人對 Shiro 的定義為好入門。

我選型為 Shiro ,主要的原因擴展太easy了,而且我要的功能它都有。

本教程開發環境

本教程Jar包管理是 Maven ,所以如果是 Maven 項目下載Demo後可以直接使用,如果是普通的Java Web項目,那麽請在下面下載所有依賴包。

本教程開發工具是Myecilpse8.5。

本教程編碼格式為UTF-8

本教程JDK為1.7,請勿使用自帶工具JDK。

本教程Mysql為5.3版本是以上。

Redis 版本隨意。

本教程Spring版本為4.2.5

前端頁面采用Bootstrap 3.2

本教程包含的內容

  1. SSM(SpringMVC + Spring + Mybatis)框架的增刪改查(含分頁),所以如果框架小白也是可以看看的。
  2. View層主要是Freemarker,但是為了考慮到好多人還使用的是JSP,也有一個頁面是用JSP實現的,並且框架支持Freemarker 和 JSPView展示(優先找Freemarker)。
  3. Shiro + Redis 的集成,也提供Ehcache的依賴Jar。
  4. Shiro 初始權限動態加載。
  5. Shiro 自定義權限校驗Filter定義,及功能實現。
  6. Shiro Ajax請求權限不滿足,攔截後解決方案。
  7. Shiro Freemarker標簽使用。
  8. Shiro JSP標簽使用。
  9. Shiro 登錄後跳轉到最後一個訪問的頁面。
  10. 用戶禁止登錄Demo
  11. 在線顯示,在線用戶管理(踢出登錄)。
  12. 登錄註冊密碼加密傳輸Demo(詳細請見下面講解)。
  13. 密碼修改。
  14. 用戶個人中心。
  15. 權限的增刪改查。
  16. 角色的增刪改查。
  17. 權限->角色->用戶之間的關系維護。
  18. 管理員權限的自動添加(當有一個權限創建,自動添加到管理員角色下,保證管理員是最大權限)。
  19. Spring定時任務數據化數據。
  20. 集成多種驗證碼(包括動態的gif驗證碼哦)。
  21. 一個帳號多處登錄限制,踢出用戶。
  22. 後續會陸陸續續升級... ...

一、SSM(SpringMVC + Mybatis)框架的增刪改查(含分頁)

本教程是SSM(SpringMVC + Spring + Mybatis + Freemarker + JSP) + Shiro + Redis 做的整體Demo,其他框架需要自己自行解決,所以不做其他框架的講解,其實是大同小異。

Controller ==> Service(事務控制層) ==> Dao ==> SqlMapper ==> Mysql

二、View層 Freemarker,JSP

通用View層配置在spring-mvc.xml中的以【通用試圖解析器】註釋標註的區間配置。

三、Shiro + Redis 的集成,也提供Ehcache的依賴Jar。

Redis 緩存配置主要在spring-cache.xml中。對應的所有Cache 相關 Java 代碼在package:com.sojson.core.shiro.cache

四、Shiro 初始權限動態加載。

我們一般是這麽加載的。在spring-shiro.xml中配置

  1. <property name="filterChainDefinitions" >
  2. <value>
  3. /** = anon
  4. /page/login.jsp = anon
  5. /page/register/* = anon
  6. /page/index.jsp = authc
  7. /page/addItem* = authc,roles[數據管理員]
  8. /page/file* = authc,roleOR[普通用戶,數據管理員]
  9. /page/listItems* = authc,roleOR[數據管理員,普通用戶]
  10. /page/showItem* = authc,roleOR[數據管理員,普通用戶]
  11. /page/updateItem*=authc,roles[數據管理員]
  12. </value>
  13. </property>

本教程采用動態加載,你可以從數據庫裏讀取然後拼接成shiro要的數據。

  1. <property name="filterChainDefinitions" value="#\{shiroManager.loadFilterChainDefinitions()\}"/>

配置文件方式加載詳細講解:https://www.sojson.com/blog/148.html

五、Shiro 自定義權限校驗Filter定義,及功能實現。

Shiro Filter在package:com.sojson.core.shiro.filter,具體配置在spring-shiro.xml中。定義了5個攔截器,具體功能看代碼以及代碼註釋。

  1. <bean id="shiroManager" class="com.sojson.core.shiro.service.impl.ShiroManagerImpl"/>
  2. <bean id="login" class="com.sojson.core.shiro.filter.LoginFilter"/>
  3. <bean id="role" class="com.sojson.core.shiro.filter.RoleFilter"/>
  4. <bean id="permission" class="com.sojson.core.shiro.filter.PermissionFilter"/>
  5. <bean id="simple" class="com.sojson.core.shiro.filter.SimpleAuthFilter"/>
  1. <property name="filters">
  2. <util:map>
  3. <entry key="login" value-ref="login"></entry>
  4. <entry key="role" value-ref="role"></entry>
  5. <entry key="simple" value-ref="simple"></entry>
  6. <entry key="permission" value-ref="permission"></entry>
  7. </util:map>
  8. </property>

六、Shiro Ajax請求權限不滿足,攔截後解決方案。

這裏有一個前提,我們知道Ajax不能做頁面redirectforward跳轉,所以Ajax請求假如沒登錄,那麽這個請求給用戶的感覺就是沒有任何反應,而用戶又不知道用戶已經退出了。解決代碼如下:

  1. //Java代碼,判斷如果是Ajax請求,然後並且沒登錄,那麽就給予返回JSON,login_status = 300,message = 當前用戶沒有登錄!
  2. if (ShiroFilterUtils.isAjax(request)) {// ajax請求
  3. Map<String,String> resultMap = new HashMap<String, String>();
  4. LoggerUtils.debug(getClass(), "當前用戶沒有登錄,並且是Ajax請求!");
  5. resultMap.put("login_status", "300");
  6. resultMap.put("message", "\u5F53\u524D\u7528\u6237\u6CA1\u6709\u767B\u5F55\uFF01");//當前用戶沒有登錄!
  7. ShiroFilterUtils.out(response, resultMap);
  8. }

  1. //前端代碼
  2. if(result.login_status == 300){
  3. layer.msg(result.message);//當前用戶沒有登錄!
  4. }

七、Shiro Freemarker標簽使用。

Freemarker使用Shiro 標簽的介紹:https://www.sojson.com/blog/143.html

八、Shiro JSP標簽使用。

JSP使用Shiro 標簽的介紹:https://www.sojson.com/blog/144.html

九、Shiro 登錄後跳轉到最後一個訪問的頁面。

在 Java 中就可以這樣獲取上一個地址:

  1. //上一個瀏覽的非Ajax的地址,在登錄後,取得地址,如果不為null,那麽就跳轉過去。
  2. String url = (String) request.getAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE);
  3. //shiro也有他的方法。詳細看下面。

如果需要保存登錄之前的Request信息,那麽需要在Login攔截的Filter中先保存:

  1. @Override
  2. protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
  3. throws Exception {
  4. //保存Request和Response,登錄後可以取到
  5. saveRequestAndRedirectToLogin(request, response);
  6. return Boolean.FALSE ;
  7. }
  8. //登錄後,取到之前的Request中的一些信息。
  9. SavedRequest saveRequest = WebUtils.getSavedRequest(request);
  10. saveRequest.getMethod();//之前的請求方法
  11. saveRequest.getQueryString();//之前請求的條件
  12. saveRequest.getRequestURI();//之前請求的路徑
  13. saveRequest.getRequestUrl();//之前請求的全路徑

十、用戶禁止登錄Demo

這個功能其實是一個改變用戶數據庫表裏的一個字段,本Demo中:1:有效,0:禁止登錄

然後踢出用戶登錄狀態。代碼詳細請查看CustomSessionManager.java類的forbidUserById(Long id, Long status)方法。

而再次登錄的話,需要再登錄,而登錄的地方限制了用戶狀態為(0:禁止登錄)的用戶登錄。

  1. /**
  2. * 查詢要禁用的用戶是否在線。
  3. * @param id 用戶ID
  4. * @param status 用戶狀態
  5. */
  6. public void forbidUserById(Long id, Long status) {
  7. //獲取所有在線用戶
  8. for(UserOnlineBo bo : getAllUser()){
  9. Long userId = bo.getId();
  10. //匹配用戶ID
  11. if(userId.equals(id)){
  12. //獲取用戶Session
  13. Session session = shiroSessionRepository.getSession(bo.getSessionId());
  14. //標記用戶Session
  15. SessionStatus sessionStatus = (SessionStatus) session.getAttribute(SESSION_STATUS);
  16. //是否踢出 true:有效,false:踢出。
  17. sessionStatus.setOnlineStatus(status.intValue() == 1);
  18. //更新Session
  19. customShiroSessionDAO.update(session);
  20. }
  21. }
  22. }

十一、在線顯示,在線用戶管理(踢出登錄)

上面的功能依賴這個功能。從Redis中獲取所有有效的Session

  1. /**
  2. * 獲取所有的有效Session用戶
  3. * @return
  4. */
  5. public List getAllUser() {
  6. //獲取所有session
  7. Collection sessions = customShiroSessionDAO.getActiveSessions();
  8. List list = new ArrayList();
  9. for (Session session : sessions) {
  10. UserOnlineBo bo = getSessionBo(session);
  11. if(null != bo){
  12. list.add(bo);
  13. }
  14. }
  15. return list;
  16. }

踢出後,不能直接退出,要不然用戶感覺莫名其妙。所有增加了一個Filter。SimpleAuthFilter.java如果標記為踢出,會提示用戶。具體查看源碼以及配合項目的使用。

十二、登錄註冊密碼加密傳輸

這個地方好多人糾結的。比如密碼過於簡單,即使加密後也能破解。如我們把密碼:123456,加密後就是:e10adc3949ba59abbe56e057f20f883e

這個很容易被識別,導致不安全,現在市面上的MD5破解其實就是把常用的數字,字母進行先加密,然後對比,美其名曰破解MD5。

那怎麽能讓用戶即使使用很簡單的密碼,也發現不了?

本Demo的實現方式是:MD5(登錄帳號 + “固定值” + 密碼),把這個作為密碼,這樣,基本是不可能猜的出來。

  1. //Java代碼。UserManager.md5Pswd(UUser user);
  2. /**
  3. * 加工密碼,和登錄一致。
  4. * @param user
  5. * @return
  6. */
  7. public static UUser md5Pswd(UUser user){
  8. //密碼為 email + ‘#‘ + pswd,然後MD5
  9. user.setPswd(md5Pswd(user.getEmail(),user.getPswd()));
  10. return user;
  11. }
  12. /**
  13. * 字符串返回值
  14. * @param email
  15. * @param pswd
  16. * @return
  17. */
  18. public static String md5Pswd(String email ,String pswd){
  19. pswd = String.format("%s#%s", email,pswd);
  20. pswd = MathUtil.getMD5(pswd);
  21. return pswd;
  22. }
  1. //JS代碼
  2. var pswd = MD5(username +"#" + password);

十三、密碼修改

不講了,和上面原理一致,然後具體看Demo。

十四、用戶個人中心

包含的功能有[個人資料,資料修改,密碼修改,我的權限],具體看Demo。

十五、權限的增刪改查。

Demo的設計是遵循RBAC3的思想。https://www.sojson.com/blog/142.html

RBAC個人理解介紹:https://www.sojson.com/blog/141.html

技術分享圖片

具體實現看Demo。

十六、角色的增刪改查

技術分享圖片

十七、權限->角色->用戶之間的關系維護

把權限賦給角色。

技術分享圖片

把角色賦給用戶。

技術分享圖片

十八、管理員權限的自動添加

這裏每次添加一個權限,都會添加到“管理員”角色下,保證“管理員”角色擁有最大權限。

十九、Spring定時任務數據初始化

這個Demo因為是開放的,所以創建了一個定時任務。每20分鐘執行一次,用Mysql存儲過程重新創建表,重新插入初始化數據。

具體數據看項目中的init/sql下的tables.sql(初始化表),init.data.sql(初始化數據)。

  1. //定時任務配置文件spring-timer.xml
  2. <task:executor id="executor" pool-size="5" />
  3. <task:scheduler id="scheduler" pool-size="10" />
  4. <task:annotation-driven executor="executor" scheduler="scheduler" />
  5. //Java 代碼 RoleServiceImpl.java
  6. /**
  7. * 每20分鐘執行一次
  8. */
  9. @Override
  10. @Scheduled(cron = "0 0/20 * * * ? ")
  11. public void initData() {
  12. roleMapper.initData();
  13. }

二十、集成驗證碼

技術分享圖片

項目中package:com.sojson.common.utils.vcode包是驗證碼的封裝包。

並且提供了一個VerifyCodeUtils.java 的驗證碼工具類。

使用方法參見:CommonController.java類中的getVCode()方法和getGifCode()方法。

技術分享圖片技術分享圖片

驗證碼詳細介紹、
Java生成驗證碼合集(一)簡單版 、
Java生成驗證碼合集(二)GJF版 。

二十一、一個帳號多處登錄限制,踢出用戶。

項目中我們會用到單點登錄,還有用到單個賬號怎麽限制同時只能一個人在線?

Shiro教程(十一)Shiro 控制並發登錄人數限制實現,登錄踢出實現:https://www.sojson.com/blog/158.html

如果不是Maven項目,下載依賴包。

依賴Jar包下載:

項目依賴Jar包,或者請加QQ群:259217951(群文件內有,有問題可以交流。)。

備註:點擊文件名下載,附件源來自雲端,只能在本站下載。復制下載鏈接無效。

Shiro + SSM框架 Demo 源碼下載。

源碼下載

Shiro_SSM_0.1版本下載(求你了,別下。)

Shiro_SSM_0.2版本下載(最後更新時間,2017年5月9日 )

備註:點擊文件名下載,附件源來自雲端,只能在本站下載。復制下載鏈接無效。

如果本文對你有幫助,那麽請你贊助我,讓我更有激情的寫下去,幫助更多的人。

版權所屬:SO JSON在線解析

原文地址:https://www.sojson.com/shiro

轉載時必須以鏈接形式註明原始出處及本聲明。

Shiro Demo 示例(SpringMVC-Mybatis-Shiro-redis)