Shiro極簡入門

Shiro是什麼

Apache提供的Java輕量級安全框架, 相比Spring Security更爲簡單。
作用主要包括: 認證、授權、加密和會話管理。

核心概念:

Subject: 主體
對應應用程序的用戶(User),Shiro爲了避免衝突,從前安全角度起的名字, 實際就是當前登錄的用戶。

SecurityManager-安全管理器
用於管理主體以及權限。

Realms:域
充當Shiro與應用程序的安全數據之間的“橋樑”或“連接器”。也就是Shiro會從應用程序中獲取身份驗證和授權的信息。
簡單點說,就是安全數據源。 應用中至少需要配置一個Relam,可以使用多種方式,比如.ini的文件,JDBC數據庫連接或是LDAP。

SecurityManager的初始化

在Web應用中,通過在web.xml中配置Shiro的Servlet過濾器;
在獨立應用中,可以通過多種配置方式,包括Java代碼、Spring XML,YAML、.properties和.ini文件。

以INI配置爲例:shiro.ini

[users]
oscar = 123456, admin

[roles]
admin = *

[users] 配置靜態的用戶列表, 方便測試
[roles] 配置角色和權限

主體、角色和權限
主體分配角色, 角色分配權限
比如:主體:root, 角色:admin, 權限: *
root用戶擁有admin角色,admin角色擁有所有權限。

在老版本中, SecurityManager通過工廠類的方式初始化,但是現在這種方式已經廢棄了, 不建議使用。
Factory factory = new IniSecurityManagerFactory(“classpath:shiro.ini”);
SecurityManager securityManager = factory.getInstance();

新版本 SecurityManager初始化方法
DefaultSecurityManager securityManager = new DefaultSecurityManager();
IniRealm iniRealm = new IniRealm(“classpath:shiro.ini”);
securityManager.setRealm(iniRealm);

用戶認證(Authentication)

用戶認證是認證該用戶是否是應用的合法用戶。

認證步驟:

  1. 收集用認證的身份信息, 以用戶名密碼登錄爲例,產生的認證Token如下:

AuthenticationToken token = new UsernamePasswordToken(“oscar”, “123456”);

  1. 獲取當前主體
    Subject currentUser = SecurityUtils.getSubject();

  2. 使用產生的Token登錄
    currentUser.login(token);
    該方法可以通過異常捕獲獲取異常信息,比如密碼錯誤等。

授權(Authorization)

認證後的用戶是否對應用的資源、頁面等有權限訪問。Shiro主要通過角色(Role)和權限(Permission)實現。
授權可以判斷該用戶是否具有某個角色,或是該主體對某個類或是實例是否有權限操作, 代碼示例如下:

        //4.1 是admin角色
        if(currentUser.hasRole("admin")) {
            
        }
        //4.2 有創建用戶權限(類層級)
        if (currentUser.isPermitted("user:create") ) {
            
        }
        //4.3 有刪除oscar這個用戶的權限(實例層級)
        if (currentUser.isPermitted("user:delete:oscar") ) {
            
        }
public class ShiroDemo {

    public static void main(String[] args) {

        
        //1. 初始化安全管理器SecurityManager
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
        securityManager.setRealm(iniRealm);
        SecurityUtils.setSecurityManager(securityManager);
        
        //2. 獲取主體
        Subject currentUser = SecurityUtils.getSubject();
        
        //3.用戶名/密碼驗證
        if (!currentUser.isAuthenticated()) {
            System.out.println("開始驗證");
            UsernamePasswordToken token = new UsernamePasswordToken("oscar", "123456");
            token.setRememberMe(true);
            try {
                currentUser.login(token);
            } catch (UnknownAccountException uae) {
                System.out.println("用戶不存在:" + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                System.out.println("密碼錯誤: " + token.getPrincipal() + " ");
            } catch (LockedAccountException lae) {
                System.out.println("賬號被鎖了");
            }
            
            
            System.out.println("驗證成功");
        }
        
        //4. 授權判斷
        //4.1 是admin角色
        if(currentUser.hasRole("admin")) {
            
        }
        //4.2 有創建用戶權限(類層級)
        if (currentUser.isPermitted("user:create") ) {
            
        }
        //4.3 有刪除oscar這個用戶的權限(實例層級)
        if (currentUser.isPermitted("user:delete:oscar") ) {
            
        }
        
        //5.登出
        currentUser.logout();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章