安全框架Shiro入門

来源:http://www.cnblogs.com/liyuhui-Z/archive/2017/11/09/7804877.html
-Advertisement-
Play Games

Shiro簡介 Apache Shiro是Java的一個安全框架,官網為shiro.apache.org,主要場景為控制登陸,判斷用戶是否有訪問某個功能的許可權等等。 Shiro的核心功能(入門知識,只介紹前兩個) 認證 授權 會話管理 加密 引入jar包和配置web.xml 引入Shiro對應的ja ...


Shiro簡介

Apache Shiro是Java的一個安全框架,官網為shiro.apache.org,主要場景為控制登陸,判斷用戶是否有訪問某個功能的許可權等等。

Shiro的核心功能(入門知識,只介紹前兩個)

  • 認證

  • 授權

  • 會話管理

  • 加密

引入jar包和配置web.xml

  • 引入Shiro對應的jar包,下麵給出Maven

    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-all</artifactId>
        <version>1.2.2</version>
    </dependency>
    
  • 在web.xml中配置spring框架提供的用於整合shiro框架的過濾器

        <!-- 配置shiro過濾器 -->
    <filter>
        <filter-name>shiroFilter</filter-name>    // 需要在spring的配置文件中創建一個bean(shiroFilter)
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>   
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    下麵我們將要進行Shiro的認證功能和授權功能的實現,代碼比較多。

登錄方法的實現

Shiro認證的流程

  • Application Code:應用程式代碼, 即登錄方法(登錄方法不是直接查詢資料庫,而是調用Shiro框架提供的介面來實現)

  • Subject:框架提供的介面,代表當前用戶對象

  • SecurityManager:框架提供的介面,代表安全管理器對象

  • Realm:可以開發人員編寫(即認證和授權方法)

  1. 我們首先將登錄方法按照Shiro指定的方式進行改進

     public String login() {
        // 獲取驗證碼
        String validateCode = (String) ServletActionContext.getRequest().getSession().getAttribute("key");
        // 判斷驗證碼
        if (StringUtils.isNotBlank(checkcode) && checkcode.equals(validateCode)) {  
            // 獲取getSubject對象,Shiro中代表當前用戶對象
            Subject subject = SecurityUtils.getSubject();
    
            // 令牌 傳遞進去前臺接受的賬號和密碼
            AuthenticationToken token = new UsernamePasswordToken(model.getUsername(),
                    MD5Utils.md5(model.getPassword()));// 創建用戶名密碼令牌對象
            try {
                subject.login(token); // 調用內置的登錄方法來實現檢驗 如果登陸錯誤就會拋出異常,返回登錄頁面
            } catch (Exception e) {
                e.printStackTrace();
                return LOGIN;
            }
            User user = (User) subject.getPrincipal();   // 登錄成功後可以從subject取得登錄對象
            ServletActionContext.getRequest().getSession().setAttribute("loginUser", user);
            return HOME;
    
        } else {
            this.addActionError("輸入驗證碼錯誤");
            return LOGIN;
        }
    
    }
    
  2. 然後編寫Realm繼承AuthorizingRealm ,即編寫具體的認證和授權方法

        public class BOSRealm extends AuthorizingRealm {
        @Autowired
        private IUserDao userDao
    
        // 授權方法
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
            // 可以在這裡將用戶所屬的許可權查詢出來,然後遍歷賦值給info對象,這樣就可以實現了授權
            // 判斷訪問路徑或者方法有沒有許可權的時候就是根據info中的數據來判斷
            info.addStringPermission("staff-list");
            return info;
        }
        // 認證方法(登陸方法)
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
            System.out.println("認證...");
            UsernamePasswordToken passwordToken = (UsernamePasswordToken) arg0;   // 對象轉換
            String username = passwordToken.getUsername();   // 獲得username
            User user = userDao.findByUsername(username);    // 通過username從資料庫中獲取到User對象
            if (user == null) {
                return null;
            }
            // 內置驗證方法 (資料庫中獲取的對象,對象的密碼, this.getName())
            AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());  
            return authenticationInfo;
        }
    
    }
  3. 到上面以後編碼工作就完成了,剩下的就是進行配置了,首先將編寫的Realm註入到安全管理器,整合的是Spring,所以下麵的配置都是在Spring配置文件中。

    <!-- 註冊realm -->
    <bean id="bosRealm" class="lyh.bos.realm.BOSRealm"></bean>
    
    <!-- 註冊安全管理器對象 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm"/>
    </bean>
    
  4. 配置ShiroFilterFactoryBean,同時還可以配置一下URL攔截規則,註意這裡的id要和web.xml<filter-name>shiroFilter</filter-name>相同

    <!-- shiro 配置 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  <!-- 此處為web.xml配置的攔截器 -->
        <!-- 註入安全管理器對象 -->
        <property name="securityManager" ref="securityManager"/>   
        <!-- 註入相關頁面訪問URL -->
        <property name="loginUrl" value="/login.jsp"/>          <!-- 登錄頁面 -->
        <property name="successUrl" value="/index.jsp"/>   <!-- 登錄成功的主頁 -->
        <property name="unauthorizedUrl" value="/unauthorized.jsp"/>   <!-- 許可權不足轉向的錯誤頁面 -->
                <property name="unauthorizedUrl" value="/unauthorized.jsp"/> 
        <!--註入URL攔截規則, -->
        <!-- anon 都可以訪問   
                       perms["staff-list"] 是否有staff-list許可權 
                       authc 登錄才可以訪問 -->
        <property name="filterChainDefinitions">  
            <value>
                /css/** = anon
                /admin/logout = logout    <!-- 註銷,訪問這個路徑,自動註銷不需要自己編寫方法 -->
                /images/** = anon
                /validatecode.jsp* = anon
                /login.jsp = anon
                /userAction_login.action = anon
                /page_base_staff.action = perms["staff-list"]   <!-- 表示page_base_staff.action路徑需要有staff-list許可權才可訪問 -->
                /* = authc    
            </value>
        </property>
    </bean>
    
  5. Shiro還提供了使用註解控制許可權的方法,開啟方式如下,同時,使用的註解許可權還需要配置全局異常,用來捕獲當許可權不足拋出異常時轉向的頁面,這裡使用的是SpringMVC,開啟方式@RequiresPermissions("staff-list")

        <!-- 開啟註解配置許可權 -->
    <bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        <!-- 必須使用cglib方式為       Action對象創建代理對象 -->
        <property name="proxyTargetClass" value="true"/>
    </bean>
    
    <!-- 配置shiro框架提供的切麵類,用於創建代理對象 -->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/> 
    // 配置全局異常處理器
        <!-- 需要進行許可權控制的頁面訪問 -->
    <global-results>
        <result name="login">/login.jsp</result>
        <result name="unauthorized">/unauthorized.jsp</result>
    </global-results>
    
    <!-- 全局異常處理 -->
    <global-exception-mappings>
        <exception-mapping result="unauthorized" exception="org.apache.shiro.authz.UnauthorizedException"></exception-mapping>
    </global-exception-mappings>

Shiro提供的控制許可權的方式

  • URL許可權攔截控制

  • 方法註解許可權控制

  • 頁面標簽許可權控制(當有對應的許可權就顯示對應的頁面元素,沒有許可權則不顯示), 需要在對應的頁面引入Shiro的標簽庫
    <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>,可以用在HTMl也可以用在JS中。

  • 代碼級別許可權控制(在方法內添加代碼)

Shiro整合ehcache緩存許可權數據

如果訪問一個頁面就執行一次授權,就會訪問資料庫,浪費資源,所以我們可以使用ehcache來進行緩存許可權,只要登錄時進行一次授權,後面無需再次授權,直接使用緩存。

shiro自動整合ehcache,只需要簡單配置就能使用。

  • 在根目錄下建立ehcache.xml

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
            maxElementsInMemory="10000"    
            eternal="false"
            timeToIdleSeconds="600"
            timeToLiveSeconds="600"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />
    
    <!-- 
        記憶體中最多可以存儲多少個數據 
        是否永久有效
        空閑時間
        存活時間
        記憶體空間不夠是否存儲到磁碟
        磁碟最大存儲個數
        伺服器重啟,磁碟數據是否需要
        線程
        淘汰策略(最近最少使用)  
     -->  
    </ehcache>
  • 在spring配置文件中配置緩存管理器對象,並註入給安全管理器對象

        <!-- 註冊ehcache -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml" />
    </bean>
  • 將ehcache註入到shiro的配置管理器,shiro會自動使用緩存管理,在原來的管理器中添加<property name="cacheManager" ref="cacheManager"/> 一條語句即可。
        <!-- 註冊安全管理器對象 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="bosRealm"/>
        <!-- 將ehcache註入shiro -->
        <property name="cacheManager" ref="cacheManager"/>
    </bean>

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • fileStream:操作位元組的,也就是所有的文件都可以拿它去操作 / file / path / streamRead / streamWrite(這兩個都是操作字元的,它所操作的都是文本文件) fileStream 與file的區別,fileStream可以操作大文件,因為fileStream是 ...
  • 返回目錄 應該這樣理解它 非同步,早期開發人員對它有很多誤解,認為不阻塞主線程就是非同步,更有認為不阻塞UI就是非同步,但非同步歸根結底和這兩個東西關係並不大,非同步的出現主要是為了提高線程的利用率,讓可用線程更高,而不是一個線程只做一件事,這件事沒有完成就不去做下麵的事情,這是不正確的,線程應該被解放出來! ...
  • 封裝、繼承、多態,面向對象的三大特性,前兩項理解相對容易,但要理解多態,特別是深入的瞭解,對於初學者而言可能就會有一定困難了。我一直認為學習OO的最好方法就是結合實踐,封裝、繼承在實際工作中的應用隨處可見,但多態呢?也許未必,可能不經意間用到也不會把它跟“多態”這個詞對應起來。在此拋磚引玉,大家討論 ...
  • springmvc+hibernate+jdbctemplate+mysql 原文鏈接:http://blog.csdn.net/rugaxm/article/details/8551905 先看下麵小段代碼,一個controller,一個service。 controller.java代碼: .. ...
  • 在APP中內嵌H5頁面,若頁面上存在下載鏈接,沒有任何反應,為什麼呢? 原因是app中內嵌的H5頁面是WebView解析的,什麼是WebView呢? 在Android手機中內置了一款高性能webkit內核瀏覽器,在SDK中封裝為一個叫做WebView組件。 WebView控制調用相應的WEB頁面進行 ...
  • 前言 在使用tomcat時,經常會遇到連接數、線程數之類的配置問題,要真正理解這些概念,必須先瞭解Tomcat的連接器(Connector)。 在前面的文章 詳解Tomcat配置文件server.xml 中寫到過:Connector的主要功能,是接收連接請求,創建Request和Response對象 ...
  • 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/7804185.html 前面講到:Java IO編程全解(五)——AIO編程 為了防止由於對一些技術概念和術語的理解或者叫法不一致而引起歧義,這裡對涉及到的專業術語或者技術用語做下聲明:如果它們與其他一些地方的 ...
  • 三大特征:封裝,繼承,多態 多態:簡單的說就是用同樣的對象引用調用同樣的方法但是做了不同的事情。 抽象:抽象是將一類對象的共同特征總結出來構造類的過程 包裝,可以講基本類型當做對象來使用,抽象只關心對象有那些屬性和行為,而不關心這些行為的細節是什麼。 Integer:當數值在 128 127之間的時 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...