Realm
Realm類通過繼承AuthorizingRealm將獲取 Subject 相關(guān)信息分成兩步:獲取身份驗證信息(doGetAuthenticationInfo)及授權(quán)信息(doGetAuthorizationInfo)笔时;
1、doGetAuthenticationInfo 獲取身份驗證相關(guān)信息:首先根據(jù)傳入的用戶名獲取 User 信息;然后如果 user 為空扮饶,那么拋出沒找到帳號異常 UnknownAccountException;如果 user 找到但鎖定了拋出鎖定異常 LockedAccountException墓律;最后生成 AuthenticationInfo 信息拂盯,交給間接父類 AuthenticatingRealm 使用 CredentialsMatcher 進(jìn)行判斷密碼是否匹配,如果不匹配將拋出密碼錯誤異常 IncorrectCredentialsException奥秆;另外如果密碼重試此處太多將拋出超出重試次數(shù)異常 ExcessiveAttemptsException;在組裝 SimpleAuthenticationInfo 信息時咸灿,需要傳入:身份信息(用戶名)构订、憑據(jù)(密文密碼)、鹽(username+salt)避矢,CredentialsMatcher 使用鹽加密傳入的明文密碼和此處的密文密碼進(jìn)行匹配悼瘾。
2、doGetAuthorizationInfo 獲取授權(quán)信息:PrincipalCollection 是一個身份集合审胸,調(diào)用 getPrimaryPrincipal 得到之前傳入的用戶名亥宿;然后根據(jù)用戶名調(diào)用 UserService 接口獲取角色及權(quán)限信息。
1.AuthenticationToken
根據(jù)源碼有:
public class UsernamePasswordToken implements HostAuthenticationToken, RememberMeAuthenticationToken
public interface HostAuthenticationToken extends AuthenticationToken
public interface RememberMeAuthenticationToken extends AuthenticationToken
所以:
AuthenticationToken用于收集用戶提交的身份(如用戶名)及憑據(jù)(如密碼):
public interface AuthenticationToken extends Serializable {
Object getPrincipal();
Object getCredentials();
}
1.直接通過AuthenticationToken獲得用戶信息:
String username = (String)token.getPrincipal();
User user = userService.findByUsername(username);
2.由于繼承關(guān)系砂沛,通過UsernamePasswordToken獲得用戶信息:
UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
String username = upToken.getUsername();
String password = new String( upToken.getPassword());
RememberMeAuthenticationToken:提供了 “boolean isRememberMe()” 現(xiàn)“記住我”的功能烫扼;
HostAuthenticationToken:提供了 “String getHost()” 方法用于獲取用戶 “主機(jī)” 的功能。
UsernamePasswordToken:用于實現(xiàn)用戶名 / 密碼 Token 組碍庵,另外其實現(xiàn)了 RememberMeAuthenticationToken 和 HostAuthenticationToken映企,可以實現(xiàn)記住我及主機(jī)驗證的支持。
2.AuthenticationInfo
AuthenticationInfo 有兩個作用:
1.如果 Realm 是 AuthenticatingRealm 子類静浴,則提供給 AuthenticatingRealm 內(nèi)部使用的 CredentialsMatcher 進(jìn)行憑據(jù)驗證堰氓;(如果沒有繼承它需要在自己的 Realm 中自己實現(xiàn)驗證);
2.提供給 SecurityManager 來創(chuàng)建 Subject(提供身份信息)苹享;
MergableAuthenticationInfo 用于提供在多 Realm 時合并 AuthenticationInfo 的功能双絮,主要合并 Principal、如果是其他的如 credentialsSalt得问,會用后邊的信息覆蓋前邊的囤攀。
比如 HashedCredentialsMatcher,在驗證時會判斷 AuthenticationInfo 是否是 SaltedAuthenticationInfo 子類宫纬,來獲取鹽信息抚岗。
Account 相當(dāng)于我們之前的 User,SimpleAccount 是其一個實現(xiàn)哪怔;在 IniRealm宣蔚、PropertiesRealm 這種靜態(tài)創(chuàng)建帳號信息的場景中使用向抢,這些 Realm 直接繼承了 SimpleAccountRealm,而 SimpleAccountRealm 提供了相關(guān)的 API 來動態(tài)維護(hù) SimpleAccount胚委;即可以通過這些 API 來動態(tài)增刪改查 SimpleAccount挟鸠;動態(tài)增刪改查角色 / 權(quán)限信息。及如果您的帳號不是特別多亩冬,可以使用這種方式艘希,具體請參考 SimpleAccountRealm Javadoc。
其他情況一般返回 SimpleAuthenticationInfo 即可硅急。
3.PrincipalCollection
因為我們可以在 Shiro 中同時配置多個 Realm覆享,所以呢身份信息可能就有多個;因此其提供了 PrincipalCollection 用于聚合這些身份信息营袜。
因為 PrincipalCollection 聚合了多個撒顿,此處最需要注意的是 getPrimaryPrincipal,如果只有一個 Principal 那么直接返回即可荚板,如果有多個 Principal凤壁,則返回第一個(因為內(nèi)部使用 Map 存儲,所以可以認(rèn)為是返回任意一個)跪另;
4.AuthorizationInfo
AuthorizationInfo 用于聚合授權(quán)信息的:
public interface AuthorizationInfo extends Serializable {
Collection<String> getRoles();
Collection<String> getStringPermissions();
Collection<Permission> getObjectPermissions();
}
當(dāng)我們使用 AuthorizingRealm 時拧抖,如果身份驗證成功,在進(jìn)行授權(quán)時就通過 doGetAuthorizationInfo 方法獲取角色 / 權(quán)限信息用于授權(quán)驗證免绿。
Shiro 提供了一個實現(xiàn) SimpleAuthorizationInfo唧席,大多數(shù)時候使用這個即可。