天天看點

shiro實戰系列(一)之入門實戰

一、什麼是shiro?

Apache Shiro 是一個強大而靈活的開源安全架構,它幹淨利落地處理身份認證,授權,企業會話管理和加密。   Apache Shiro 的首要目标是易于使用和了解。安全有時候是很複雜的,甚至是痛苦的,但它沒有必要這樣。架構應 該盡可能掩蓋複雜的地方,露出一個幹淨而直覺的 API,來簡化開發人員在使他們的應用程式安全上的努力。  

二、shiro可以做什麼?

 驗證使用者來核實他們的身份。

 對使用者執行通路控制,

如:

(1) 判斷使用者是否被配置設定了一個确定的安全角色

(2)判斷使用者是否被允許做某事

 在任何環境下使用 Session API,即使沒有 Web 或 EJB 容器。

 在身份驗證,通路控制期間或在會話的生命周期,對事件作出反應。

 聚集一個或多個使用者安全資料的資料源,并作為一個單一的複合使用者“視圖”。

 啟用單點登入(SSO)功能。

 為沒有關聯到登入的使用者啟用"Remember Me"服務。

Shiro 視圖在所有應用程式環境下實作這些目标——從最簡單的指令行應用程式到最大的企業應用,不強制依賴其 他第三方架構,容器,或應用伺服器。當然,該項目的目标是盡可能地融入到這些環境,但它能夠在任何環境下立 即可用。  

三、shiro結構圖

shiro實戰系列(一)之入門實戰

Shiro 把 Shiro 開發團隊稱為“應用程式的四大基石”——身份驗證,授權,會話管理和加密作為其目标。 

shiro核心四要素,簡單的概述為認證,授權,會話,加密等。

 Authentication:有時也簡稱為“登入”,這是一個證明使用者是他們所說的他們是誰的行為。

 Authorization:通路控制的過程,也就是絕對“誰”去通路“什麼”。

 Session Management:管理使用者特定的會話,即使在非 Web 或 EJB 應用程式。

 Cryptography:通過使用加密算法保持資料安全同時易于使用。

額外的功能概述:

 Web Support:Shiro 的 web 支援的 API 能夠輕松地幫助保護 Web 應用程式。

 Caching:緩存是 Apache Shiro 中的第一層公民,來確定安全操作快速而又高效。

 Concurrency:Apache Shiro 利用它的并發特性來支援多線程應用程式。

 Testing:測試支援的存在來幫助你編寫單元測試和內建測試,并確定你的能夠如預期的一樣安全。

 "Run As":一個允許使用者假設為另一個使用者身份(如果允許)的功能,有時候在管理腳本很有用。

 "Remember Me":在會話中記住使用者的身份,是以他們隻需要在強制時候登入。

四、簡單的使用程式

示例為maven工程,jdk8,maven3以上

(1)pom依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.apache.shiro.tutorials</groupId>
    <artifactId>shiro-tutorial</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

      <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency> 
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.1.0</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>


            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <classpathScope>test</classpathScope>
                    <mainClass>Tutorial</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>      

logger4j.properties配置檔案内容:

如果不加入,将無法看到log4j日志列印的結果

#config root logger
log4j.rootLogger = INFO,system.out
log4j.appender.system.out=org.apache.log4j.ConsoleAppender
log4j.appender.system.out.layout=org.apache.log4j.PatternLayout
log4j.appender.system.out.layout.ConversionPattern=[Log]%-d{yyyy-MM-dd HH:mm:ss} %5p[%F:%L]:%m%n
#log4j.appender.system.out.layout.ConversionPattern=[Log] %5p[%F:%L]:%m%n

#config this Project.file logger
log4j.logger.thisProject.file=INFO,thisProject.file.out
log4j.appender.thisProject.file.out=org.apache.log4j.DailyRollingFileAppender
log4j.appender.thisProject.file.out.File=pmslogout.log
log4j.appender.thisProject.file.out.layout=org.apache.log4j.PatternLayout
log4j.appender.thisProject.file.out.layout.ConversionPattern=[Log]%-d{yyyy-MM-dd HH:mm:ss} %5p[%F:%L]:%m%n
log4j.appender.thisProject.file.append=true      

(2)運作main方法

import org.apache.log4j.Logger;

public class Tutorial {


    

    private static Logger logger = Logger.getLogger(Tutorial.class);
    
    public static void main(String[] args) {
    
        logger.info("Hello Wolrd Apache Shiro Application");
        System.exit(0);
    }
    }

      

Enable Shiro

在應用程式中啟用 Shiro 最先要明白的事情是幾乎在 Shiro 中的每個東西都與一個名為 SecurityManager 的主要的/核 心的元件有關。對于那些熟悉 Java 安全的人來說,這是 Shiro 的 SecurityManager 概念——它不等同于 java.lang.SecurityManager。  

現在了解 Shiro 的 SecurityManager 是應用程式的 Shiro 環境的核心及每個應用程式中必須存在一個 SecurityManager 是很有益處的。是以,在我們的實戰系列應用程式中第一 件要做的事情就是配置 SecurityManager 執行個體。

Configuration

雖然我們能夠直接執行個體化一個 SecurityManager 類,但 Shiro 的 SecurityManager 實作有足夠的配置選項及内置元件 使得在 Java 源代碼做這件事情變得較為痛苦——如果使用一個靈活的基于文本的配置格式來配置 SecurityManager, 那麼這将是一件很容易的事情。 

為此,Shiro 通過基于文本的 INI 配置檔案提供了一個預設的"共性(common denominator)"解決方案。近來人們已 經相當厭倦了使用笨重的 XML 檔案,且 INI 檔案易于閱讀,使用簡單,依賴性低。你稍後将會看到有了對象導航圖 的簡單了解,INI 檔案能夠有效地被用來配置簡單的對象圖,如 SecurityManager。

Many Configuration Options

Shiro 的 SecurityManager 實作及所有支援元件都是相容 JavaBean 的。這允許 Shiro 能夠與幾乎任何配置格式如 XML(Spring,JBoss,Guice 等等),YAML,JSON,Groovy Builder markup,以及更多配置被一起配置。INI 檔案隻是 Shiro 的“共性”格式,他它允許任何環境下的配置,除非其他選項不可用。

上面的簡單應用僅僅隻是證明加入shiro相關的依賴運作沒問題,下面進入簡單的真正實戰

shiro.ini檔案

權限角色相關的規則就在該檔案中編寫:

[user]
root = secret,admin
guest = guest,guest
presidentskroob = 12345,president
darkhelmet = ludicrousspeed,darklord,schwartz
lonestarr=vespa,goodguy,schwartz

[roles]
admin = *j
schwartz = lightsaber:*
goodguy = winnebago:drive:eagle5      

main方法運作:

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.util.Factory;

public class Tutorial {


    

    private static Logger logger = Logger.getLogger(Tutorial.class);
    
    public static void main(String[] args) {
    
        logger.info("My First Apache Shiro Application");
        /**
         *步驟一: 我們使用 Shiro 的 IniSecurityManager 實作來提取我們的 shiro.ini 檔案,它位于 classpath 的根目錄。
         * 該實作反映了 Shiro 對工廠設計模式的支援。
         * classpath: 字首是一個資源定位符,用來告訴 shiro 去哪加載 ini 檔案(其 他字首,如 url:和 file:也同樣被支援)。 
         */
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        
        /**
         * 步驟二: factory.getInstance()方法被調用,它來解析 INI 檔案并傳回反映該配置的 SecurityManager 執行個體。 
         */
        SecurityManager securityManager = factory.getInstance();
        
        /**
         * 
         * 步驟三: 在這個簡單的例子中,我們把 SecurityManager 設定為一個靜态的(memory)單例,能夠跨 JVM 通路。
         * 但請 注意,這是不可取的,如果你在單個的 JVM 隻中會有不隻一個啟用 Shiro 的應用程式。對于這個簡單的例子 而言,這是沒有問題的,但更為複雜的應用程式環境通常将 SecurityManager 
         * 置于應用程式特定的存儲中(如 在 Web 應用中的 ServletContext 或 Spring,Guice 後 JBoss DI 容器執行個體)。
         */
        SecurityUtils.setSecurityManager(securityManager);
        
        System.exit(0);
        
    }
    }      

Apache Shiro簡單的權限管理架構,無論是在github還是碼雲上,看過不少項目,基本都采取了shiro作為權限控制,spring securty,這個玩意,spring本身內建,不過它并沒有shiro好了解,當然掌握好shiro對于了解spring security是非常有幫助的。