1. 程式人生 > >(3)shiro自定義realm

(3)shiro自定義realm

上面一章說到shiro的認證和授權最底層就是呼叫realm的getAuthorizationInfo(獲取使用者的角色和資源)和getAuthenticationInfo(校驗賬號密碼是否正確)兩個方法。

如果我們要從資料庫中查詢使用者和他的許可權資訊,我們可以使用shiro提供給我們的JdbcRealm

 JdbcRealm

 新增jar

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId
> <version>5.1.25</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>0.2.23</version> </dependency>

classpath環境下新建shiro-jdbc.ini如下配置
這裡我們採用了阿里巴巴的資料來源,注入到jdbcRealm的dataSource變數中,並且將這個jdbcRealm注入到securityManager,有點類似於spring的注入。

下面的sql放在github上對應的章節根目錄下,匯入即可,資料庫密碼填寫自己資料庫密碼

jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shiro
dataSource.username=root
dataSource.password=123456
jdbcRealm.dataSource=$dataSource
#注入securityManager的realm
securityManager.realms=$jdbcRealm

測試程式碼:

ShiroUtils.login("classpath:shiro-jdbc.ini","zhang","123456");
Subject subject = SecurityUtils.getSubject();
//是否通過認證
System.out.println(subject.isAuthenticated());

 

其中ShiroUtils的登入方法(這個以後直接略過):

    public static void login(String configPath,String username,String password){
        Factory<SecurityManager> factory =new IniSecurityManagerFactory(configPath);
        //得到安全管理器
        SecurityManager securityManager = factory.getInstance();

        SecurityUtils.setSecurityManager(securityManager);

        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token = new UsernamePasswordToken(username, password);


        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }
    }
View Code

 

 

最後輸出true。

因為jdbcRealm裡面的sql都是固定的,所以我們表結構都要按照JdbcRealm裡面建立對應的表。下面是JdbcRealm裡面各種查詢的sql(salt是密碼加密,後面介紹加密再說,我們這裡直接用明文密碼)

表裡面數據分別如下

 

接著測試程式碼新增如下:

        System.out.println(subject.hasRole("role1"));

        System.out.println(subject.isPermitted("user:create"));

 

最後輸出true,false

為什麼角色role1獲取到了,permission沒有獲取到呢。

 

原因是JdbcRealm裡面有個permissionsLookupEnabled預設是false,所以不會查詢對應的資源許可權,我們在配置檔案中開啟這個查詢。

#開啟permission查詢
jdbcRealm.permissionsLookupEnabled=true

 

再查詢就是true了。

 

自定義Realm

1 新增MyRealm類直接繼承AuthorizingRealm.

public class MyRealm extends AuthorizingRealm {

    //認證資訊,
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;

        String username = upToken.getUsername();
        String password = new String(upToken.getPassword());
        //模擬使用者名稱密碼是否正確
        if(!"zhang".equals(username)){
           throw new UnknownAccountException();
        }
        if(!"123456".equals(password)){
            throw new IncorrectCredentialsException();
        }
        return new SimpleAuthenticationInfo(username,password,getName());

    }

    //授權
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //獲取使用者名稱
        String username = (String)getAvailablePrincipal(principals);
        //模擬從資料庫查詢出來對應的角色和許可權
        Set<String> roles = new HashSet<String>();
        roles.add("role_1");
        roles.add("role_2");

        Set<String> permissions = new HashSet<String>();
        permissions.add("user:create");
        permissions.add("user:delete");

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roles);
        info.setStringPermissions(permissions);
        return info;
    }


}

2,classpath檔案下新建shiro-myrealm.ini配置檔案

myrealm= com.nfcm.shiro.Realm.MyRealm
securityManager.realms=$myrealm

3,測試

        ShiroUtils.login("classpath:shiro-myrealm.ini","zhang","123456");

        Subject subject = SecurityUtils.getSubject();
        //是否通過認證
        System.out.println(subject.isAuthenticated());
        //是否有role1角色
        System.out.println(subject.hasRole("role_1"));

        System.out.println(subject.isPermitted("user:create"));

 

到這裡全部測試通過。

 

github程式碼地址

https://github.com/cmniefei/shiroparent