首页 > 代码库 > 【三】shiro入门 之 Realm

【三】shiro入门 之 Realm

Realm:域,Shiro 从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;
也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource , 即安全数据源。

Realm接口如下

String getName(); //返回一个唯一的Realm名字
boolean supports(AuthenticationToken token); //判断此Realm是否支持此Token
AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException; //根据Token获取认证信息

单Realm配置

1.自定义Realm实现

package me.shijunjie.realms;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.realm.Realm;

public class MyRealm1 implements Realm {

    public String getName() {
        return "MyRealm1";
    }

    public boolean supports(AuthenticationToken token) {
        // 仅支持UsernamePasswordToken 类型的Token
        return token instanceof UsernamePasswordToken;
    }

    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName = (String) token.getPrincipal();
        String password = new String((char[])token.getCredentials()); //得到密码
        if (!"zhang".equals(userName)) {
            throw new UnknownAccountException(); // 如果用户名错误
        }
        if (!"123".equals(password)) {
            throw new IncorrectCredentialsException(); // 如果密码错误
        }
        // 如果身份认证验证成功,返回一个AuthenticationInfo实现;
        return new SimpleAuthenticationInfo(userName, password, getName());
    }

}

2、ini配置文件指定自定义Realm实现(shiro-realm.ini)

#声明一个realm
myRealm1=me.shijunjie.realms.MyRealm1
#指定securityManager的realms实现
securityManager.realms=$myRealm1

3.测试示例

@Test
    public void testRealm() {
        // 1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
        Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
        //2、得到SecurityManager实例并绑定给SecurityUtils
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        //3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
        
        try {
        //4、登录,即身份验证
        subject.login(token);
        } catch (AuthenticationException e) {
          //5、身份验证失败
            System.out.println("身份验证失败");
        }
        
        //断言用户已经登录
        Assert.assertEquals(true, subject.isAuthenticated());
        
        subject.logout();
    }

多 Realm配置

1、ini配置文件(shiro-multi-realm.ini)

#声明一个realm
myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1
myRealm2=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm2
#指定securityManager的realms实现
securityManager.realms=$myRealm1,$myRealm2

 

1、ini配置文件(shiro-multi-realm.ini)
securityManager会按照realms指定的顺序进行身份认证。此处我们使用显示指定顺序的方
式指定了Realm的顺序,如果删除“securityManager.realms=$myRealm1,$myRealm2”,那
么securityManager会按照realm声明的顺序进行使用(即无需设置realms属性,其会自动
发现),当我们显示指定realm 后, 其他没有指定realm 将被忽略,如
“securityManager.realms=$myRealm1”,那么myRealm2 不会被自动设置进去

【三】shiro入门 之 Realm