(二)、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();
}