自定義shiro的Realm實現和CredentialsMatcher實現以及Token實現


Realm是shiro比較核心的接口,簡單說它的實現類就是校驗用戶輸入的賬號信息的地方.如果想自定義實現一般的配置文件如下:

<!--自定義Realm 繼承自AuthorizingRealm -->
    <bean id="userRealm" class="xxx.UserRealm">
<!-- 自定義比對器 --> <property name="credentialsMatcher" ref="myCredentialsMatcher"></property> </bean> <!-- 自定義匹配器 繼承自SimpleCredentialsMatcher --> <bean id="myCredentialsMatcher" class="xxx.MyCredentialsMatcher"></bean>

其中類的關鍵代碼:

public class UserRealm extends AuthorizingRealm {
    
    public UserRealm() {
        super();
    }
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//這里返回的就是你自定義Token中getPricipal返回的用戶信息對象. Object user
= principals.getPrimaryPrincipal(); ...... return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authcToken) throws AuthenticationException { Object user = authcToken.getPrincipal();
//從數據庫中查找用戶的信息
UserInfo info = Dao.selectUser(user); ...
//按照用戶的輸入的principal信息去數據庫中查詢,然后封裝出比對信息.下面的info.getPwd()代表的就是Credentials信息,一般指的密碼 SimpleAuthenticationInfo authenticationInfo
= new SimpleAuthenticationInfo(user, info.getPwd(), getName()); return authenticationInfo; }
//自定義matcher,這里就是對比用戶的輸入的信息封裝成的token和按照用戶輸入的principal(一般就是用戶名)從數據庫中查詢出的信息封裝的info信息,一般就是比對他們的Credentials
public
class MyCredentialsMatcher extends SimpleCredentialsMatcher { @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { Object tokenCredentials = getCredentials(token); Object accountCredentials = getCredentials(info); return super.equals(tokenCredentials, accountCredentials); } }

這里紅色的doGetAuthenticationInfo方法是用來按照用戶輸入的principal信息從數據庫中查詢,並將結果作為一個比對信息,比對2者的Credentials信息是否一致,比對時將調用比對器的doCredentialsMatch方法進行比對,所以我們可以在realm中配置自定義的比對器,重寫此方法來達到自定義比對方法,實現特殊的比對邏輯.尤其是token中封裝自定義對象時

.如果一致則登錄成功.而綠色的doGetAuthorizationInfo方法則是作為獲取當前用戶的角色權限相關信息的方法,此方法中要根據用戶信息查詢出相關的角色權限信息並封裝進去.有了此信息之后就可以根據角色和權限信息進行訪問權限的控制了.

一般直接使用usernamePasswordToken即可,但是由於此默認實現一般存儲的為字符串的principal和Credentials信息,如有必要改為存儲自定義對象,則可以自定義token來實現,關鍵代碼:

/* 這里必須說一下,必須要繼承UsernamePasswordToken,因為realm實現中有個suports方法,會判斷token是否被支持,默認的情況下是只支持UsernamePasswordToken的.如需要完全自定義,則需要單獨再realm配置中添加上新的自定義token的類型支持.  */
public class MyUserToken extends UsernamePasswordToken {
    //這個自定義的屬性可以是對象.
    private Object user;

    public MyUserToken() {
    }

    public MyUserToken(Objectuser) {
        this.user = user;
    }
    @Override
    public Object getPrincipal() {
//賬號信息
return user; } @Override public Object getCredentials() {
//校驗的信息,其實一般就是指密碼
return user.getPwd(); } }

 

在用戶登錄時關鍵代碼:

       Subject currentUser = SecurityUtils.getSubject();
       UserInfo user = new UserInfo();
       user.setName("aaa");
       user.setPwd("123");
        MyUserToken token = new MyUserToken(user);
        currentUser.login(token);
        if (currentUser.isAuthenticated()) {
          //登錄成功
        }else{
          //失敗
        }           

總體的思路為使用自定義的token類將用戶輸入的信息封裝,然后采用token進行login操作.此時shiro將使用token中攜帶的用戶信息調用Realm中自定義的doGetAuthenticationInfo方法進行校驗比對.比對成功則登錄成功,並會自動將相關角色權限信息封裝進去.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM