《Shiro安全框架》专题(三)-Shiro之自定义Realm

本文介绍了如何创建自定义Realm类以扩展Apache Shiro的认证和授权功能,重点讲解了继承AuthorizingRealm的原因、自定义Realm的调用时机及密码验证过程。同时,详细配置shiro.ini文件并提供测试示例。

1.自定义Realm的实现

1.1.创建自定义Realmjava类

创建一个java文件继承AuthorizingRealm类,重写两个抽象方法

package com.bruce.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * 自定义的Realm
 * @author dengp
 *
 */
public class MyRealm extends AuthorizingRealm {

    /**
     * 认证方法
     * @param token
     * 	就是我们在测试代码中 定义的UsernamePasswordToken对象
     *  有我们保存的需要验证的账号密码信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取账号信息
        String principal = (String) token.getPrincipal();
        // 正常逻辑此处应该根据账号去数据库中查询,此处我们默认账号为 root 密码123456
        // 验证账号
        if(!"root".equals(principal)){
            // 账号错误
            return null;
        }
        String pwd = "123456";
        // 验证密码
        AuthenticationInfo info = new SimpleAuthenticationInfo(principal, pwd,"myrealm");
        return info;
    }

    /**
     * 授权方法
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // TODO Auto-generated method stub
        return null;
    }
}

方法名说明
doGetAuthenticationInfo完成账号认证的方法
doGetAuthorizationInfo完成用户授权的方法

1.2.配置shiro.ini文件

[main]
#自定义 realm
customRealm=com.bruce.realm.MyRealm
#将realm设置到securityManager
securityManager.realms=$customRealm

1.3.测试

测试代码和上个案例一模一样

@Test
public void test1() {
    // 1.获取SecurityManager工厂对象
    IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
    // 2.通过Factory对象获取SecurityManager对象
    SecurityManager securityManager = factory.getInstance();
    // 3.将SecurityManager对象添加到当前运行环境中
    SecurityUtils.setSecurityManager(securityManager);
    // 4.获取Subject对象
    Subject subject = SecurityUtils.getSubject();
    AuthenticationToken token = new UsernamePasswordToken("root", "12345");
    // 登录操作
    try {
        subject.login(token);
    } catch (UnknownAccountException e) {
        System.out.println("账号出错...");
    } catch(IncorrectCredentialsException e){
        System.out.println("密码出错...");
    }
    // 获取登录的状态
    System.out.println(subject.isAuthenticated());
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.原理分析

2.1.为什么要继承AuthorizingRealm?

上个教程中我们完整的分析了认证的流程,我们发现在认证的过程核心代码是此:
在这里插入图片描述
核心方法是doGetAuthenticationInfo(token)在Realm的结构中

在这里插入图片描述
AuthorizingRealm和AuthenticatingRealm都提供的有doGetAuthenticationInfo (token) 的抽象方法。但是AuthenticatingRealm中要重写的抽象方法太多而AuthorizingRealm只需要重写两个方法,且这两个方法都是我们需要使用的。故选择继承AuthorizingRealm

2.2.自定义的Realm什么时候被调用的?

在这里插入图片描述

2.3.密码验证什么时候执行的?

注意:自定义Realm中只完成了账号的认证。密码认证还是在AuthenticatingRealm中完成的,只是我们在自定义Realm中完成了密码的设置。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

源码小哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值