java框架之shiro

#shiro簡介

1、簡介

  • Apache Shiro 是一個強大而靈活的開源安全框架,能夠用於應用程序的身份驗證,受權,會話管理和加密。
    • Authentication:有時也簡稱爲「登陸」,這是一個證實用戶是他們所說的他們是誰的行爲。
    • Authorization:訪問控制的過程,也就是絕對「誰」去訪問「什麼」。
    • Session Management:管理用戶特定的會話,即便在非 Web 或 EJB 應用程序。
    • Cryptography:經過使用加密算法保持數據安全同時易於使用。

2、主要功能&附加特性

 

3、第一個shiro程序

一、使用說明

  • maven構建工程,log4j輸出日誌java

  • idea終端裏,當前工程目錄下使用 mvn compile exec:java 命令運行程序,直接運行測試的類不會輸出測試的信息

二、目錄結構

三、關鍵文件內容及代碼

  • pom文件
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://maven.apache.org/POM/4.0.0"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.stan</groupId>
        <artifactId>shiro</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <name>shiro-start</name>
        <packaging>jar</packaging>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <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>
                        <encoding>${project.build.sourceEncoding}</encoding>
                    </configuration>
                </plugin>
                <!-- This plugin is only to test run our little application. It is not
                needed in most Shiro-enabled applications: -->
                <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>QuickStart</mainClass>
                    </configuration>
                </plugin>
            </plugins>
        </build>
        <dependencies>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>1.1.0</version>
            </dependency>
            <!-- Shiro use SLF4J for logging. We'll use the 'simple' binding
            in this example app. See http://ww.slf4j.org for more info. -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-simple</artifactId>
                <version>1.6.1</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </project>
  • shiro配置文件
    [users]
    root = secret, admin
    guest = guest, guest
    presidentskroob = 12345, president
    darkhelmet = ludicrousspeed, darklord, schwartz
    lonestarr = vespa, goodguy, schwartz
    
    [roles]
    admin = *
    schwartz = lightsaber:*
    goodguy = winnebago:drive:eagle5
  • log4j配置文件
    log4j.rootLogger=INFO, stdout
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
    # General Apache libraries
    log4j.logger.org.apache=WARN
    # Spring
    log4j.logger.org.springframework=WARN
    # Default Shiro logging
    log4j.logger.org.apache.shiro=TRACE
    # Disable verbose logging
    log4j.logger.org.apache.shiro.util.ThreadContext=WARN
    log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
  • 測試類
    public class QuickStart {
        private static final transient Logger log = LoggerFactory.getLogger(QuickStart.class);
    
        public static void main(String[] args) {
            log.info("My First Apache Shiro Application");
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            SecurityManager securityManager = factory.getInstance();
            SecurityUtils.setSecurityManager(securityManager);
            //get the currently executing user:
            Subject currentUser = SecurityUtils.getSubject();
            //Do some stuff with a Session (no need for a web or EJB container!!!)
            Session session = currentUser.getSession();
            session.setAttribute("someKey", "aValue");
            String value = (String) session.getAttribute("someKey");
            if (value.equals("aValue")) {
                log.info("Retrieved the correct vlaue! [" + value + "]");
            }
            //let's login the current user so we can check against roles and permissions:
            if (!currentUser.isAuthenticated()) {
                UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "1223");
                token.setRememberMe(true);
                try {
                    currentUser.login(token);
                } catch (UnknownAccountException uae) {
                    log.info("There is no user with username of " + token.getPrincipal());
                } catch (IncorrectCredentialsException ice) {
                    log.info("Password for account " + token.getPrincipal() + " was incorrect!");
                } catch (LockedAccountException lae) {
                    log.info("The account for username " + token.getPrincipal() + " is locked. " +
                            "Please contact your administrator to unlock it.");
                }
                // … catch more exceptions here (maybe custom ones specific to your application?
                catch (AuthenticationException ae) {
                    //unexpected condition? error?
                }
            }
            //say who they are:
            //print their identifying principal (in this case, a username):
            log.info("User [" + currentUser.getPrincipal() + " ] logged in successfully.");
            //test a role:
            if (currentUser.hasRole("schwartz")) {
                log.info("May the Schwartz be with you!");
            } else {
                log.info("Hello, mere mortal.");
            }
            //test a typed permission (not instance-level)
            if (currentUser.isPermitted("lightsaber:weild")) {
                log.info("You may use a lightsaber ring. Use it wisely.");
            } else {
                log.info("Sorry, lightsaber rings are for schwartz masters only.");
            }
            //a (very powerful) Instance Level permission:
            if (currentUser.isPermitted("winnebago:drive:eagle5")) {
                log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5' . " +
                        "Here are the keys - have fun!");
            } else {
                log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
            }
            //all done - log out!
            currentUser.logout();
            System.exit(0);
        }
    }

四、總結

  • SecurityManager 不是 java.lang 包裏的那個,而是 shiro框架裏的,是shiro的核心組件,shiro不少功能的實現都要依賴於這個組件;
  • shiro 裏的 subject 表明的是當前用戶的概念

 

#shiro的架構&配置

1、架構

一、架構圖

二、shiro各個組件的說明

  • Subject:當前與軟件進行交互的實體(用戶,第三方服務等)的安全特定「視圖」。
  • SecurityManager:SecurityManager 是 Shiro 架構的心臟。它基本上是一個「保護傘」對象,協調其管理的組件以確保它們可以一塊兒順利的工做。它還管理每一個應用程序用戶的 Shiro 的視圖,所以它知道如何執行每一個用戶的安全操做。
  • Authenticator:Authenticator 是一個對執行及對用戶的身份驗證(登陸)嘗試負責的組件。Authenticator 知道如何與一個或多個 Realm 協調來存儲相關的用戶信息,從中得到的數據被用來驗證用戶的身份來保證用戶確實是他們所說的他們是誰。
  • Authorizer:是負責在應用程序中決定用戶的訪問控制的組件,是一種最終斷定用戶是否被容許作某事的機制。他知道如何協調多個後臺數據源來訪問角色特化權限信息,而後使用該信息來準確地決定用戶是否被容許執行給定的動做。
  • SessionManager:SessionManager知道如何去建立及管理用戶 Session 生命週期來爲全部環境下的用戶提供一個強健的 Session體驗。Shiro 擁有可以在任何環境下本地化管理用戶Session的能力,不依賴於特定的應用環境(如web環境),它將會使用它內置的企業級會話管理來提供一樣的編程體驗。
  • SessionDAO:表明 SessionManager 執行 Session 持久化(CRUD)操做。這容許任何數據存儲被插入到會話管理的基礎之中。
  • CacheManager:建立並管理其餘 Shiro 組件使用的 Cache 實例生命週期,支持集成第三方的緩存框架來提升性能
  • Cryptography:shiro有不少易於使用和理解編碼器實現。Shiro的加密組件簡化了複雜的Java複雜的本地密碼支持,使加密對於普通人也易於使用Realms:Realm 充當了 Shiro 與應用安全數據間的「橋樑」或者「鏈接器」。也就是說,當對用戶執行認證(登陸)和受權(訪問控制)驗證時,Shiro 會從應用配置的 Realm 中查找用戶及其權限信息。從這個意義上講,Realm 實質上是一個安全相關的 DAO:它封裝了數據源的鏈接細節,並在須要時將相關數據提供給 Shiro 。當配置 Shiro時,你必須至少指定一個 Realm ,用於認證和(或)受權。配置多個 Realm 是能夠的,可是至少須要一個。 Shiro 內置了能夠鏈接大量安全數據源(又名目錄)的 Realm,如 LDAP、關係數據庫(JDBC)、相似 INI 的文本配置資源以及屬性文件等。若是缺省的 Realm 不能知足需求,你還能夠插入表明自定義數據源的本身的 Realm 實現

三、SecurityManger的設計

  • SecurityManager要實現的功能不少,一個類要實現這麼多的功能任務會比較繁重;
  • SM實際上就是一個輕量級的容器,經過組合的設計思想將實現具體功能的各個類組合在一塊兒進行管理,提升了框架的靈活性和可插拔性;
  • Sm及其組件都是兼容javaBean的,能夠很方便配置到Spring等框架中使用,而且有很好的可插拔性;

2、核心配置

 

 

#

相關文章
相關標籤/搜索