天天看點

shiro入門

Apache Shiro 是 Java 的一個安全(權限)架構。相比于spring security 更加簡單,而且夠用。

• Shiro 可以非常容易的開發出足夠好的應用,其不僅可以用在

JavaSE 環境,也可以用在 JavaEE 環境。

• Shiro 可以完成:認證、授權、加密、會話管理、與Web 內建、 緩存

等。

• 下載下傳:

http://shiro.apache.org/

•Authentication:身份認證/登入,驗證使用者是不是擁有相應的身份;

• Authorization:授權,即權限驗證,驗證某個已認證的使用者是否擁有某個權限;即判斷用

戶是否能進行什麼操作,如:驗證某個使用者是否擁有某個角色。或者細粒度的驗證某個使用者

對某個資源是否具有某個權限;

• Session Manager:會話管理,即使用者登入後就是一次會話,在沒有退出之前,它的所有

資訊都在會話中;會話可以是普通 JavaSE 環境,也可以是 Web 環境的;

• Cryptography:加密,保護資料的安全性,如密碼加密存儲到資料庫,而不是明文存儲;

• Web Support:Web 支援,可以非常容易的內建到Web 環境;

• Caching:緩存,比如使用者登入後,其使用者資訊、擁有的角色/權限不必每次去查,這樣可

以提高效率;

• Concurrency:Shiro 支援多線程應用的并發驗證,即如在一個線程中開啟另一個線程,能

把權限自動傳播過去;

• Testing:提供測試支援;

• Run As:允許一個使用者假裝為另一個使用者(如果他們允許)的身份進行通路;

• Remember Me:記住我,這個是非常常見的功能,即一次登入後,下次再來的話不用登

錄了

下面是shiro的hello world程式。

你需要引入相關jar。

[users]
#使用者'root' 的密碼是 'secret' 角色是'admin'
root = secret, admin
#使用者'guest' 的密碼是 'guest' 角色是'guest'
guest = guest, guest

#使用者jk,密碼是jinkai,角色有2個role1和role2
jk = jinkai, role1,role2

[roles]
#角色admin 用通配符*辨別
admin = *

# 角色role1 可以對fuck做任何操作:
role1 = fuck:*

# goodguy 這個角色可以對使用者zhangsan進行删除操作
goodguy = user:delete:zhangsan
           
package com.shiro.helloworld;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Quickstart {
    private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
    public static void main(String[] args) {
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        //擷取目前的subject
        Subject currentUser = SecurityUtils.getSubject();
        // 測試使用session,沒有web或者ejb容器的環境也可以。
        Session session = currentUser.getSession();
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("---> Retrieved the correct value! [" + value + "]");
        }

        // 測試目前使用者是否已經被認證,即是否正常登入。
        if (!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken("jk", "jinkai");
            // rememberme
            token.setRememberMe(true);
            try {
                //執行登入
                currentUser.login(token);
            } 
            // 若沒有指定賬戶,則 shiro抛出UnknownAccountException異常. 
            catch (UnknownAccountException uae) {
                log.info("----> There is no user with username of " + token.getPrincipal());
                return; 
            } 
            // 若賬戶存在,但是密碼不比對,則 shiro 抛出 IncorrectCredentialsException  
            catch (IncorrectCredentialsException ice) {
                log.info("----> Password for account " + token.getPrincipal() + " was incorrect!");
                return; 
            } 
            // 使用者被鎖定,抛出 LockedAccountException
            catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            // 所有認證時異常的父類 
            catch (AuthenticationException ae) {

            }
        }

        log.info("----> User [" + currentUser.getPrincipal() + "] logged in successfully.");

        //測試是否有某個角色
        if (currentUser.hasRole("role1")) {
            log.info("----> 有role1角色!");
        } else {
            log.info("---->沒有role1角色!");
            return; 
        }
        //  測試使用者是否具備某一行為。
        if (currentUser.isPermitted("fuck:up")) {
            log.info("----> You can fuck up.");
        } else {
            log.info("Sorry, you cannot.");
        }

        //測試使用者是否具備某一行為,更具體。
        if (currentUser.isPermitted("user:delete:zhangsan")) {
            log.info("----> You can delete zhangsan - have fun!");
        } else {
            log.info("Sorry, you aren't allowed to delete zhangsan!");
        }
        //all done - 退出!
        System.out.println("---->" + currentUser.isAuthenticated());
        currentUser.logout();
        System.out.println("---->" + currentUser.isAuthenticated());
        System.exit(0);
    }
}