Shiro自定义Realm实现认证和授权(五)上

简介: Shiro自定义Realm实现认证和授权(五)

一. 为什么要自定义Realm


前面,我们在配置 Shiro 的用户信息和权限数据的时候,都是从 shiro.ini 配置文件里面读取的,


这些数据能不能从我们本地的数据库中进行读取呢? 当然可以, 可以通过 JdbcRealm 进行读取,


但是通过 JdbcRealm进行读取时,数据库的表的名称,表的字段都必须固定,非常不利于扩展。


所以,我们需要自定义Realm.


自定义Realm 时,我们常常 使用 org.apache.shiro.realm.AuthorizingRealm 类。


让我们自定义的类, 继承 AuthorizingRealm 抽象类


public abstract class AuthorizingRealm
       extends AuthenticatingRealm
      implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware{
  ...
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection);
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken)
  ...
}


AuthorizingRealm 有两个抽象方法, doGetAuthorizationInfo 和 doGetAuthenticationInfo


其中, doGetAuthorizationInfo 进行授权操作, doGetAuthenticationInfo 进行认证操作。


认证操作时,常常返回 AuthenticationInfo的子类 SimpleAuthenticationInfo


授权操作时, 常常返回 AuthorizationInfo的子类 simpleAuthorizationInfo


关于Shiro 自定义 Realm获取数据的使用方式,我们详细了解一下。


二. 自定义Realm 获取虚拟的认证授权数据


二.一 创建自定义Realm,继承 AuthorizingRealm 接口


MyRealm


package com.yjl.customer;
public class MyRealm extends AuthorizingRealm{
  @Override
  public String getName() {
    return "MyRealm";
  }
  //授权
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection) {
    return null;
  }
  //认证
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken)
      throws AuthenticationException {
    return null;
  }
}


二.二 创建配置文件 customer.ini,用于注入自定义的Realm


[main]
#配置自定义realm
myRealm=com.yjl.customer.MyRealm
#注入自定义的realm
securityManager.realm=$myRealm


二.三 在MyRealm 文件中编写认证的操作


//认证
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken)
      throws AuthenticationException {
    System.out.println("进入认证");
    //获取要登录的用户信息
    //UsernamePasswordToken token=(UsernamePasswordToken)paramAuthenticationToken;
    //获取用户名
    //String userName=token.getUsername();
    //也可以通过获取身份信息,然后转成 String 类型
    String userName=(String)paramAuthenticationToken.getPrincipal();
    //从数据库里面查询该用户的密码,省略数据库查询,直接固化下来,该用户的密码就是 1234 
    String password="1234"; 
    SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(userName, password, 
        getName());
    return simpleAuthenticationInfo;
  }


SimpleAuthenticationInfo 对象里面放置三个参数, 身份,证明 和 getName()


二.四 在MyRealm 文件中编写授权的操作


  //授权
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection) {
    //获取凭证 用户名
    System.out.println("进入授权");
    String userName=(String)(paramPrincipalCollection.getPrimaryPrincipal());
    System.out.println("输出登录者的凭证:"+userName);
    if(userName==null){ //未认证通过的情况
      return null;
    }
    //模拟权限,手动添加
    List<String> priList=new ArrayList<String>();
    //依旧没有修改的权限
    priList.add("user:add");
    priList.add("user:delete");
    priList.add("user:select");
    priList.add("user:toList");
    //创建 SimpleAuthorizationInfo 对象
    SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
    //添加角色, 通常不用角色判断,用权限判断
    simpleAuthorizationInfo.addRole("role1");
    for(String pri:priList){
      //添加权限
      simpleAuthorizationInfo.addStringPermission(pri);
    }
    return simpleAuthorizationInfo;
  }


这样,一个自定义的 Realm 就实现了


二.五 编写测试 MyRealmTest


package com.yjl.customer;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
public class MyRealmTest {
  public static void main(String[] args) throws Exception{
    //1. 创建factory
    Factory<SecurityManager> factory=new IniSecurityManagerFactory("classpath:customer.ini");
    //2 获取实例
    SecurityManager securityManager=factory.getInstance();
    //3 设置
    SecurityUtils.setSecurityManager(securityManager);
    //4. 获取 Subject
    Subject subject=SecurityUtils.getSubject();
    //5. 设置token
    UsernamePasswordToken token=new UsernamePasswordToken("yuejl","1234");
    //6. 执行登录操作
    try{
      subject.login(token); 
      System.out.println(subject.getPrincipal()+"登录成功");
      boolean flag=subject.hasRole("role1");
      System.out.println("是否拥有角色 role1:"+flag);
      //关于角色验证的那些方法,都可以使用
      flag=subject.hasRole("role2");
      System.out.println("是否拥有角色role2:"+flag);
      //关于权限验证的那些方法,都可以使用
      flag=subject.isPermitted("user:add");
      System.out.println("是否拥有权限 user:add "+flag);
      flag=subject.isPermitted("user:update");
      System.out.println("是否拥有权限 user:update "+flag);
    }catch(Exception e){
      e.printStackTrace();
      System.out.println("用户名或者密码不正确");
    }
  }
}


控制台打印输出:


20200513143512930.png


权限检查了四次,所以调用了四次 doGetAuthorizationInfo() 方法, 很浪费资源, 所以常常会进行缓存处理,后面老蝴蝶会讲缓存处理。


发现,我们可以实现自定义的Realm.


然而,用户的密码和权限数据,都只是模拟数据,能不能换成真实的数据,真正从数据库里面查询的呢?



相关文章
|
6月前
|
数据库
shiro认证和授权
shiro认证和授权
58 3
|
6月前
|
数据库 数据安全/隐私保护
Shiro【自定义Realm 、多Realm认证 、多Realm认证策略、异常处理】(四)-全面详解(学习总结---从入门到深化)
Shiro【自定义Realm 、多Realm认证 、多Realm认证策略、异常处理】(四)-全面详解(学习总结---从入门到深化)
132 1
|
6月前
|
数据库 数据安全/隐私保护
Shiro【自定义Realm 、多Realm认证 、多Realm认证策略、异常处理】(二)-全面详解(学习总结---从入门到深化)
Shiro【自定义Realm 、多Realm认证 、多Realm认证策略、异常处理】(二)-全面详解(学习总结---从入门到深化)
403 0
|
6月前
|
Java 数据安全/隐私保护
Shiro - 授权那些事
Shiro - 授权那些事
57 0
|
6月前
|
缓存 安全 数据安全/隐私保护
Shiro - 认证那些事
Shiro - 认证那些事
45 0
Shrio配置多个Realm、SecurityManager认证策略
Shrio配置多个Realm、SecurityManager认证策略
140 0
|
Java 数据安全/隐私保护
【Shiro】1、Shiro实现登录授权认证功能(下)
之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧
135 0
|
安全 Java 数据库连接
【Shiro】1、Shiro实现登录授权认证功能(上)
之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧
316 0
|
Java 数据安全/隐私保护
【Shiro】1、Shiro实现登录授权认证功能(中)
之前在 SSM 项目中使用过 shiro,发现 shiro 的权限管理做的真不错,但是在 SSM 项目中的配置太繁杂了,于是这次在 SpringBoot 中使用了 shiro,下面一起看看吧
136 0
|
Java Apache Maven
Shiro--从一个简单的 Realm 开始权限认证
通过上篇文章的学习,小伙伴们对 shiro 应该有了一个大致的了解了,本文我们就来通过一个简单的案例,先来看看 shiro 中登录操作的一个基本用法。
Shiro--从一个简单的 Realm 开始权限认证