005 自定义Realm

Posted 最爱五仁月饼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了005 自定义Realm相关的知识,希望对你有一定的参考价值。

一 . 概述

  上几节我们一直再使用int文件充当realm,现在这一届我们就使用自定义的Realm完成认证和授权操作.

  在前面我们分析到我们的自定义的Realm需要继承AuthorizingRealm这个类.


 

二 . 编写自定义Realm 

public class CustomRealm extends AuthorizingRealm{
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        return null;
    }
    
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

}

我们首先定义一个类继承了AuthorizingRealm这个类,其中需要我们实现的是两个方法.

 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException

认证方法 : 通过用户传入的tokean对象进行认证操作,认证成功就返回用户的身份信息.认证失败就抛出异常.

 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

授权方法:通过传入的身份信息,获取用户具有的权限信息(角色和权限).


三 .实现Realm

public class CustomRealm extends AuthorizingRealm{
    //认证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken info) throws AuthenticationException {
        //获取账号和密码
        UsernamePasswordToken token = (UsernamePasswordToken) info;
        String username = token.getUsername();
        String password = new String(token.getPassword());
        //这里模拟一下认证
        if(!"trek".equals(username)) {
            throw new UnknownAccountException("账号不存在!");
        }
        if(!"123".equals(password)) {
            throw new IncorrectCredentialsException("密码不正确!!");
        }
        //此处说明认证是成功的了.
        //现在要返回用户的身份信息了
        SimpleAccount account = new SimpleAccount(username,password,getName());
        return account;
    }
    
    //授权的方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取身份信息,这里的参数就是上面方法的返回值
        String  uaername = (String) principals.getPrimaryPrincipal();
        //--通过身份信息查询用户的角色和权限信息
        Set<String> roles = new HashSet<String>();
        roles.add("admin");
        Set<String> pers = new HashSet<String>();
        pers.add("user:add");
        //返回授权信息
        SimpleAuthorizationInfo info  =new  SimpleAuthorizationInfo();
        info.addRoles(roles);
        info.addStringPermissions(pers);
        return info;
    }

}

我们实现了自定的Realm.


四 .配置Realm

[main]
realm=com.trek.shiro.base.CustomRealm
securityManager.realm=$realm

将我们的ini文件变成如上的内容,现在我们的账号和密码信息都是从我们的自定义Realm之中获取的.

上面的代码相当于Spring的IOC的配置方式,比较容易理解.

测试代码:

//实现shiro的认证过程
        //创建SecurityManager
        SecurityManager securityManager = new IniSecurityManagerFactory("classpath:shiro.ini").createInstance();
        //将当前的SecurityManager设置到当前的环境之中
        SecurityUtils.setSecurityManager(securityManager);
        
        //下面实现的是一个登陆的功能
        //获取Subkect,相当与一个Currentuser
        Subject currentUser = SecurityUtils.getSubject();
        
        //创建认证需要的token
        UsernamePasswordToken token = new UsernamePasswordToken("trek","123");
        
        //实现登录功能
        try {
            currentUser.login(token);
        } catch (AuthenticationException e) {
            logger.info("认证失败,账号为{},密码为{}",token.getUsername(),new String(token.getPassword()));
            throw new AuthenticationException();
        }
        
        logger.info("认证成功!!");
        
        //此处完成shiro的授权操作
        
        //角色授权
        logger.info("当前的用户是否具有admin的角色{}",currentUser.hasRole("admin"));
        
        //权限授权
        logger.info("当前的用户是否具有user:add的权限{}",currentUser.isPermitted("user:add"));

上述的测试代码和我们之前的代码没有变过,改变的只是我们的Realm的实现.


五 .总结Realm的定制

自定义Realm比较简单,流程都是一致的,只是我们的账号,密码,角色,权限信息的获取方式不一样了.

 

以上是关于005 自定义Realm的主要内容,如果未能解决你的问题,请参考以下文章

Realm保留一个已删除的对象

shiro调用不到自定义realm

权限框架 - shiro 自定义realm

shiro自定义realm,模拟数据库查询验证

Shiro安全框架学习02 - 自定义Realm

Shiro Review——自定义Realm实现认证