• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Spring Boot 集成Shiro的多realm实现以及shiro基本入门教程

springboot 搞代码 4年前 (2022-01-09) 22次浏览 已收录 0个评论

情景

我的项目中有六个用户角色(学校管理员,学生等),需要进行分别登陆。如果在一个realm中,对controller封装好的Token进行Service验证,需要在此realm中注入六个数据库操作对象,然后写一堆if语句来判断应该使用那个Service服务,然后再在验证方法(doGetAuthorizationInfo)中写一堆if来进行分别授权,这样写不仅会让代码可读性会非常低而且很难后期维护修改(刚写完的时候只有上帝和你能看懂你写的是什么,一个月之后你写的是什么就只有上帝能看懂了)。
所以一定要配置多个realm来分别进行认证授权操作。shiro有对多个realm的处理,当配置了多个Realm时,shiro会用自带的org.apache.shiro.authc.pam.ModularRealmAuthenticator类的doAuthenticate方法来进行realm判断,源码:

protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws Authenticatio<span style="color:transparent">来1源gaodai#ma#com搞*代#码1网</span>nException {
    assertRealmsConfigured();
    Collection<Realm> realms = getRealms();
    if (realms.size() == 1) {
      return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
    } else {
      return doMultiRealmAuthentication(realms, authenticationToken);
    }
  }

assertRealmsConfigured();的作用是验证realm列表是否为空,如果一个realm也没有则会抛出IllegalStateException异常(爆红:Configuration error: No realms have been configured! One or more realms must be present to execute an authentication attempt.)
当realm只有一个时直接返回,当realm有多个时返回所有的realm。而我们要做的就是写多个realm后重写ModularRealmAuthenticator下的doAuthenticate方法,使它能满足我们的项目需求。
那么改怎么重写ModularRealmAuthenticator下的doAuthenticate方法,使它能满足我们的项目需求呢?这就需要分析我们使用shiro的使用方法了。

shiro的使用

1.Controller层中,获取当前用户后将用户名和密码封装UsernamePasswordToken对象,然后调用Subject中的登陆方法subject.login(UsernamePasswordToken)

 @RequestMapping("/user/login")
	@ResponseBody
  public String Login(String userName,String password){
    //获取当前用户 subject
    Subject subject = SecurityUtils.getSubject();
    //封装用户的登陆数据
    UsernamePasswordToken token = 
    new UsernamePasswordToken(userName, password);
    try{
      subject.login(token);//执行登陆方法
      return "登陆成功";
    }catch (UnknownAccountException e){//用户名不存在
      model.addAttribute("msg","用户名不存在");
      return "用户名不存在";
    }catch (IncorrectCredentialsException e){//密码错误
      model.addAttribute("msg","密码错误");
      return "密码错误";
    }
  }

(为了测试方便,我用了@ResponseBody返回字符串)
2.完善自定义Realm类,继承于AuthorizingRealm,主要实现doGetAuthorizationInfo和doGetAuthenticationInfo方法
(需要实现认证和授权方法,在这里方便测试主要是认证)

public class StudentRealm extends AuthorizingRealm {
  @Resource
  private StudentsService studentsService;
  //授权
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    return null;
  }

  //认证
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    System.out.println("Shiro=========Student认证");
    UserToken userToken = (UserToken) token;
    Students students = studentsService.queryByNum(userToken.getUsername());
    //账号不存在
    if (students == null) {
      System.out.println("学生不存在");
      //向上层提交UnknownAccountException异常,在controller层处理
      throw new UnknownAccountException();
    }
    //密码认证,shiro来做,可以自定义加密方式
    return new SimpleAuthenticationInfo("", students.getPassword(), USER_LOGIN_TYPE);
  }
}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Spring Boot 集成Shiro的多realm实现以及shiro基本入门教程
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址