1. 程式人生 > >Shiro+SpringMVC 實現更安全的登入(加密匹配&登入失敗超次數鎖定帳號)

Shiro+SpringMVC 實現更安全的登入(加密匹配&登入失敗超次數鎖定帳號)

前言

初學shiro,shiro提供了一系列安全相關的解決方案,根據官方的介紹,shiro提供了“身份認證”、“授權”、“加密”和“Session管理”這四個主要的核心功能,如下圖所示:


本篇blog主要用到了Authentication(身份認證)和Cryptography(加密),並通過這兩個核心模組來演示shiro如何幫助我們構建更安全的web project中的登入模組,實現了安全的密碼匹配和登入失敗超指定次數鎖定賬戶這兩個主要功能,下面一起來體驗一下。

身份認證與加密

如果簡單瞭解過shiro身份認證的一些基本概念,都應該明白shiro的身份認證的流程,大致是這樣的:當我們呼叫subject.login(token)的時候,首先這次身份認證會委託給

Security Manager,而Security Manager又會委託給Authenticator,接著Authenticator會把傳過來的token再交給我們自己注入的Realm進行資料匹配從而完成整個認證。如果不太瞭解這個流程建議再仔細讀一下官方提供的Authentication說明文件:

接下來通過程式碼來看看,理論往往沒有說服力,首先看一下專案結構(具體可在blog尾部下載原始碼參考):


專案通過Maven的分模組管理按層劃分,通過最常用的spring+springmvc+mybatis來結合shiro進行web最簡單的登入功能的實現,首先是登入頁面:


我們輸入使用者名稱和密碼點選submit則跳到UserController執行登入的業務邏輯,接下來看看UserController的程式碼:

  1. package com.firstelite.cq.controller;  
  2. import java.text.SimpleDateFormat;  
  3. import java.util.Date;  
  4. import javax.servlet.http.HttpServletRequest;  
  5. import org.apache.shiro.SecurityUtils;  
  6. import org.apache.shiro.authc.AuthenticationException;  
  7. import org.apache.shiro.authc.ExcessiveAttemptsException;  
  8. import org.apache.shiro.authc.IncorrectCredentialsException;  
  9. import org.apache.shiro.authc.UnknownAccountException;  
  10. import org.apache.shiro.authc.UsernamePasswordToken;  
  11. import org.apache.shiro.subject.Subject;  
  12. import org.springframework.stereotype.Controller;  
  13. import org.springframework.web.bind.annotation.RequestMapping;  
  14. @Controller
  15. @RequestMapping(value = "user")  
  16. publicclass UserController extends BaseController {  
  17.     @RequestMapping(value = "/LoginPage")  
  18.     public String loginPage() {  
  19.         String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")  
  20.                 .format(new Date());  
  21.         System.out.println(now + "to LoginPage!!!");  
  22.         return"login";  
  23.     }  
  24.     @RequestMapping(value = "/login")  
  25.     public String login(HttpServletRequest request, String username,  
  26.             String password) {  
  27.         System.out.println("username:" + username + "----" + "password:"
  28.                 + password);  
  29.         Subject subject = SecurityUtils.getSubject();  
  30.         UsernamePasswordToken token = new UsernamePasswordToken(username,  
  31.                 password);  
  32.         String error = null;  
  33.         try {  
  34.             subject.login(token);  
  35.         } catch (UnknownAccountException e) {  
  36.             error = "使用者名稱/密碼錯誤";  
  37.         } catch (IncorrectCredentialsException e) {  
  38.             error = "使用者名稱/密碼錯誤";  
  39.         } catch (ExcessiveAttemptsException e) {  
  40.             // TODO: handle exception
  41.             error = "登入失敗多次,賬戶鎖定10分鐘";  
  42.         } catch (AuthenticationException e) {  
  43.             // 其他錯誤,比如鎖定,如果想單獨處理請單獨catch處理
  44.             error = "其他錯誤:" + e.getMessage();  
  45.         }  
  46.         if (error != null) {// 出錯了,返回登入頁面
  47.             request.setAttribute("error", error);  
  48.             return"failure";  
  49.         } else {// 登入成功
  50.             return"success";  
  51.         }  
  52.     }  
  53. }  

很簡單,上面的程式碼在shiro官方的10min-Tutorial就有介紹,這是shiro進行身份驗證時最基本的程式碼骨架,只不過我們集成了Spring之後就不用自己去例項化IniSecurityManagerFactory和SecurityManager了,shiro根據身份驗證的結果不同會丟擲各種各樣的異常類,如上的幾種異常是我們最常用的,如果還想了解更多相關的異常可以訪問shiro官方的介紹:

根據shiro的認證流程,最終Authenticator會把login傳入的引數token交給Realm進行驗證,Realm往往也是我們自己注入的,我們在debug模式下不難發現,在subject.login(token)打上斷點,F6之後會跳到我們Realm類中doGetAuthenticationInfo(AuthenticationToken token)這個回撥方法,從而也驗證了認證流程確實沒問題。下面貼出Realm中的程式碼:

  1. package com.firstelite.cq.realm;  
  2. import javax.annotation.Resource;  
  3. import org.apache.shiro.authc.AuthenticationException;  
  4. import org.apache.shiro.authc.AuthenticationInfo;  
  5. import org.apache.shiro.authc.AuthenticationToken;  
  6. import org.apache.shiro.authc.LockedAccountException;  
  7. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
  8. import org.apache.shiro.authc.UnknownAccountException;  
  9. import org.apache.shiro.authz.AuthorizationInfo;  
  10. import org.apache.shiro.realm.AuthorizingRealm;  
  11. import org.apache.shiro.subject.PrincipalCollection;  
  12. import org.apache.shiro.util.ByteSource;  
  13. import com.firstelite.cq.model.User;  
  14. import com.firstelite.cq.service.UserService;  
  15. publicclass UserRealm extends AuthorizingRealm {  
  16.     @Resource
  17.     private UserService userService;  
  18.     @Override
  19.     protected AuthorizationInfo doGetAuthorizationInfo(  
  20.             PrincipalCollection principals) {  
  21.         // TODO Auto-generated method stub
  22.         returnnull;  
  23.     }  
  24.     @Override
  25.     protected AuthenticationInfo doGetAuthenticationInfo(  
  26.             AuthenticationToken token) throws AuthenticationException {  
  27.         // TODO Auto-generated method stub
  28.         String username = (String) token.getPrincipal();  
  29.         // 呼叫userService查詢是否有此使用者
  30.         User user = userService.findUserByUsername(username);  
  31.         if (user == null) {  
  32.             // 丟擲 帳號找不到異常
  33.             thrownew UnknownAccountException();  
  34.         }  
  35.         // 判斷帳號是否鎖定
  36.         if (Boolean.TRUE.equals(user.getLocked())) {  
  37.             

    相關推薦

    Shiro+SpringMVC 實現安全登入加密匹配&登入失敗次數鎖定

    前言 初學shiro,shiro提供了一系列安全相關的解決方案,根據官方的介紹,shiro提供了“身份認證”、“授權”、“加密”和“Session管理”這四個主要的核心功能,如下圖所示: 本篇blog主要用到了Authentication(身份認證)和Cryptog

    Shiro+SpringMVC 實現安全登入加密匹配&登入失敗次數鎖定

    前言 初學shiro,shiro提供了一系列安全相關的解決方案,根據官方的介紹,shiro提供了“身份認證”、“授權”、“加密”和“Session管理”這四個主要的核心功能,如下圖所示: 本篇blog主要用到了Authentication(身份認證)和Crypto

    pac4j探索: buji-pac4j+Cas+Shiro+SpringMvc實現單點登入

    在pac4j探索的上一篇文章大致講述了一下buji-pac4j+CAS的認證流程。這裡記錄一下本人實現的最簡單的單點登入,僅作為筆記、學習交流之用,戳這裡獲取本文原始碼。 一、專案框架 1、 buji-pac4j(v.3.0.0) 2、

    支持多用戶web終端實現安全保障nodejs

    ant 設置 寬高 處理 out locking nec tdi 背景 背景 terminal(命令行)作為本地IDE普遍擁有的功能,對項目的git操作以及文件操作有著非常強大的支持。對於WebIDE,在沒有web偽終端的情況下,僅僅提供封裝的命令行接口是完全不能滿

    利用VRID/VMAC實現安全的netscaler HA故障切換

    命令 bsp 包括 ace 連接 故障 itl ip) 它的 利用VRID/VMAC實現更安全的netscaler HA故障切換 virtual MAC在故障切換(failover)中的作用。 在一個HA模式中,首要節點(primary node)擁有所有浮動IP,包

    SpringMVC實現檔案下載功能檔案匯出功能

    1.頁面程式碼 <a class="layui-btn" href="${pageContext.request.contextPath}/bAndWListManage/downloadWhiteListTmp.do" onclick="downloadTempla

    小王的尷尬日常--Openssl 實現國密演算法加密和解密

    上一次講了產生金鑰,這次我們講一下加密解密的實現。 先說一下加密解密的流程,一下這些內容都是從國密局釋出的國密標準文件裡面摘錄出來的。大家可以去國密局的網站上自己下載。 下列符號適用於本部分。 A,B:使用公鑰密碼系統的兩個使用者。 a,b

    用遞歸實現歸並排序不會呀 不知道哪裏錯了

    clas iostream ges sin ace logs div void 遞歸實現 #include<iostream> using namespace std; #include<vector> #include "Vector.h" v

    ActiveMQ的安全機制管控臺密碼的設定和mq使用者認證

    activemq的web管理介面:http://127.0.0.1:8161/admin (1)activemq管控臺使用jetty部署,所以需要修改密碼則需要修改相應的配置檔案D:\apache-activemq-5.12.0\conf\jetty-realm.properties。

    Python網路爬蟲之股票資料Scrapy爬蟲例項介紹,實現與優化!未成功生成要爬取的內容!

    結果TXT文本里面竟然沒有內容!cry~ 編寫程式: 步驟: 1. 建立工程和Spider模板 2. 編寫Spider 3. 編寫ITEM Pipelines 程式碼:成功建立 D:\>cd pycodes D:\pycodes>

    Java web過濾器驗證登入避免未經登入進入主頁

    1.首先寫一個許可權過濾filter類,實現Filter介面 1 import java.io.IOException; 2 3 import javax.servlet.Filter; 4 import javax.servlet.FilterChain; 5

    用java robot 實現關閉他人計算機僅限於安裝了java虛擬機器的使用者

    很多時候,我們希望能夠實現自動測試,自動演示功能,或者是其它的一些滑鼠和鍵盤控制的應用(比如幫人點選廣告賺利潤等)。出於這樣的目的,自從JDK1.3開始,它就為我們提供了一個用來產生本機輸入事件的機器人類 — java.awt.Robot. 下面我來詳細介紹Ro

    利用arcpy實現接邊處理arcgis要素建立、更新、圖層選擇

    之前一個專案中有關於接邊方面內容,即在兩個相鄰的行政區域內出現面數據有相鄰的部分,現在需要將相鄰部分兩個面的ID互換。具體的資料如下圖所示: 那麼如何來解決這個問題呢,首先在arcpy中可以使用 SelectLayerByLocation_management對圖層進

    Struts+Spring+Hibernate實現上傳下載spring的最低框架配置,web.xml等

    引言  檔案的上傳和下載在J2EE程式設計已經是一個非常古老的話題了,也許您馬上就能掰著指頭數出好幾個著名的大件:如SmartUpload、Apache的FileUpload。但如果您的專案是構建在Struts+Spring+Hibernate(以下稱SSH)框架上的,這些大

    python實現用戶登陸sqlite數據庫存儲用戶信息

    自動 入學 添加 sqlite數據庫 lec 輸入密碼 獲取 where char python實現用戶登陸(sqlite數據庫存儲用戶信息) 目錄 創建數據庫 數據庫管理 簡單登陸 有些地方還未完善。 創建數據庫 import sqlite3 #建一個

    成功實現NAS家庭伺服器流媒體播放、檔案共享及下載機

    一、家庭伺服器實現的主要功能 1、流媒體播放服務:利用DLNA實現電視、手機、電腦播放其上面的媒體檔案。 2、檔案共享:利用samba實現手機、電腦等終端與伺服器的檔案共享。 3、自動下載:利用aria2c實現自動下載。 先上幾張效果圖: 用orico的包裝盒做了個

    c# winform登入關閉當前form跳轉到另一個form

    賬號、密碼驗證通過後,執行以下程式碼     System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));            

    java web開發一個同一時間只能一個人登入單點登入

    對於一個帳號在同一時間只能一個人登入,可以通過下面的方法實現: 1 .在使用者登入時,把使用者新增到一個ArrayList中 2 .再次登入時檢視ArrayList中有沒有該使用者,如果ArrayList中已經存在該使用者,則阻止其登入 3 .當用戶退出時,需要從該ArrayList中刪除該使用者,這又分為

    關於Android Studio第三方登入使用QQ登入程式碼

    關於Android Studio第三方登入(使用QQ登入) 新手上路,寫的不好或者有錯誤之處請各位大神多多指教!!! 現在很多APP應用都實現了第三方登入:比如QQ登入、微信登入、微博登入等等。其實實現起來非常簡單,那麼廢話就不多說了,接下來我們看看如

    Android中儲存靜態祕鑰加密祕鑰,特殊id欄位等

    如何在App中儲存靜態祕鑰以及保證其安全性。許多的移動app需要在app端儲存一些靜態字串常量,其可能是靜態祕鑰、第三方appId等。在儲存這些字串常量的時候就涉及到了如何保證祕鑰的安全性問題。如何保證在App中靜態祕鑰唯一且正確安全,這是一個很重要的問題,公司的產品中就