1. 程式人生 > >(二)、shiro之一些重要的元件和工具類

(二)、shiro之一些重要的元件和工具類

由於筆者水平有限,難免有說不清楚,或者理解有偏差的地方,望指正。

SecurityManager:
SecurityManager是shiro的核心元件,安全管理器;它的主要實現類有DefaultWebSecurityManager,並且當你在不指定的情況下會通過以下方法進行:

protected WebSecurityManager createDefaultSecurityManager() {
        //該方法是在AbstractShiroFilter中的方法,這是在web應用中用到的過濾器,一般會在web.xml中配置ShiroFilter 而,shiroFilter則extends AbstractShiroFilter;所以當在shiro.ini中不指定或者與Spring整合的時候;便會生成這個預設的安全器類
return new DefaultWebSecurityManager(); }

SecurityManager介面繼承了Authenticator, Authorizer, SessionManager三個介面;
並且提供了一下三個方法:

    //登入
    Subject login(Subject subject, AuthenticationToken authenticationToken) throws AuthenticationException;
    //登出
    void logout(Subject subject);
    //建立Subject
Subject createSubject(SubjectContext context);

SecurityUtils:
以下是它所含的程式碼:

private static SecurityManager securityManager;
public static Subject getSubject() {
        Subject subject = ThreadContext.getSubject();
        if (subject == null) {
            subject = (new Subject.Builder()).buildSubject();
            ThreadContext.bind(subject);
        }
        return
subject; } public static void setSecurityManager(SecurityManager securityManager) { SecurityUtils.securityManager = securityManager; } public static SecurityManager getSecurityManager() throws UnavailableSecurityManagerException { SecurityManager securityManager = ThreadContext.getSecurityManager(); if (securityManager == null) { securityManager = SecurityUtils.securityManager; } if (securityManager == null) { String msg = "No SecurityManager accessible to the calling code, either bound to the " + ThreadContext.class.getName() + " or as a vm static singleton. This is an invalid application " + "configuration."; throw new UnavailableSecurityManagerException(msg); } return securityManager; }

可以將安全管理器元件,利用setSecurityManagement()方法設定到私有物件securityManager中,然後獲取到Subject物件,然後進行登入登出的操作。

Subject:
Subject current = SecurityUtils.getSubject();`Subject是一個介面;從SecurityUtils工具類中的getSubject()靜態方法中獲取得到,
方法如下:

public static Subject getSubject() {
        Subject subject = ThreadContext.getSubject();
        if (subject == null) {
            subject = (new Subject.Builder()).buildSubject();
            ThreadContext.bind(subject);
        }
        return subject;
    }

可以看出,是從當前執行緒上下文中獲取得到的;而它代表的是:A Subject represents state and security operations for a single application user. These operations include authentication (login/logout), authorization (access control), and session access. It is Shiro’s primary mechanism for single-user security functionality.

UsernamePasswordToken:
一個包含使用者名稱和密碼的令牌,這是需要去校驗的使用者資訊,Subject提供了login(token)方法;

Realm
realm是shiro中一個比較重要的介面,它提供了供應用進行安全實體如:使用者、角色和許可權的認證和授權操作。對接的資料來源可以是jdbc、file system i/o、jpa等

    String getName();

    boolean supports(AuthenticationToken token);

    AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;

但是在使用過程中,大家一般不會直接去實現Realm介面進行自定義操作,而是往往繼承它的子類:AuthenticatingRealm 、AuthorizingRealm;一般只需要繼承AuthorizingRealm便可以,因為它同時繼承了AuthenticatingRealm;有以下兩個方法需要實現:

@Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //進行授權認證
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //進行身份驗證
        return new SimpleAuthenticationInfo(username, password, "myRealm");
    }

當然,需要注意的是自定義的Realm實現類需要在初始化的配置檔案或者是spring的xml中進行新增,注給RealmSecurityManager的realms屬性

 private Collection<Realm> realms;
 public void setRealms(Collection<Realm> realms) {
        if (realms == null) {
            throw new IllegalArgumentException("Realms collection argument cannot be null.");
        }
        if (realms.isEmpty()) {
            throw new IllegalArgumentException("Realms collection argument cannot be empty.");
        }
        this.realms = realms;
        afterRealmsSet();
    }