springboot整合shiro

2023-10-29


springboot 整合shiro

一、shiro是什么?

概念: Apache Shiro 是一个强大且易用的 Java 安全框架
能做什么:Shiro可以帮我们完成 :认证、授权、加密、会话管理、与 Web 集成、缓存等。
在这里插入图片描述
主要认识::
Subject(用户):当前的操作用户 获取当前用户Subject currentUser = SecurityUtils.getSubject()
SecurityManager(安全管理器):Shiro的核心,负责与其他组件进行交互,实现 subject 委托的各种功能
Realms(数据源) :Realm会查找相关数据源,充当与安全管理间的桥梁,经过Realm找到数据源进行认证,授权等操作
Authenticator(认证器): 用于认证,从 Realm 数据源取得数据之后进行执行认证流程处理。
Authorizer(授权器):用户访问控制授权,决定用户是否拥有执行指定操作的权限。
SessionManager (会话管理器):支持会话管理
CacheManager (缓存管理器):用于缓存认证授权信息
Cryptography(加密组件):提供了加密解密的工具包

二、与springboot的整合

1.前期准备

数据库5张表:用户表 角色表 权限表 用户与角色的中间表 角色与权限的中间表
在这里插入图片描述
创建spring boot项目 导入所需要的依赖 相应的配置文件 shiro thymeleaf mybatis mysql等

页面准备:登录 主页面 等一些界面
在这里插入图片描述

2.ShiroConfiger配置类

@Configuration
public class ShiroConfiger {
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //关联默认的web安全管理
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        return shiroFilterFactoryBean;
    }

    @Bean(name = "defaultWebSecurityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
        //关联realm
        defaultWebSecurityManager.setRealm(userRealm);
        return  defaultWebSecurityManager;
    }

    //绑定
    @Bean(name = "userRealm")
    public UserRealm userRealm(){
        return  new UserRealm();
    }
}

自定义realm(认证授权)

public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
  
        return  null;
    }
}

3.过滤(拦截)

过滤规则:anon 指定url可以匿名访问 authc 需登录 authcBasic 指定url需要http认证 logout 退出登录url user需要已登录或者记住我才能访问 roles 拥有某个角色才能进入 perms 拥有某个权限才能进入等

@Configuration
public class ShiroConfiger {
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //关联默认的web安全管理
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //过滤
        //过滤规则 anon 指定url可以匿名访问 authc 需登录 authcBasic 指定url需要http认证 logout 退出登录url  user需要已登录或者记住我才能访问
        //roles 拥有某个角色才能进入 perms 拥有某个权限才能进入
        Map<String,String> map=new HashMap<>();
        map.put("/user/add","perms[/user/add]");
        map.put("/user/update","perms[/user/update]");
        map.put("/user/index","anon");
        map.put("/user/other","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        //设置登录请求
        shiroFilterFactoryBean.setLoginUrl("/user/login");
        //设置无权限登录地址
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/un");
        return shiroFilterFactoryBean;
    }

    @Bean(name = "defaultWebSecurityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
        //关联realm
        defaultWebSecurityManager.setRealm(userRealm);
        return  defaultWebSecurityManager;
    }

    //绑定
    @Bean(name = "userRealm")
    public UserRealm userRealm(){
        return  new UserRealm();
    }

书写相应的controller进行验证

4.认证

mapper层: public SysUser selectUser(@Param(“userName”) String userName); 查询数据库实现 通过用户名 查询到相应的对象
controller层:

 @RequestMapping("/login2")
    public String toLogin2(@RequestParam("username") String username, @RequestParam("password") String password, Model model, ServletRequest request){
        //获取当前用户 subject==》》表示当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的信息 成一个UsernamePasswordToken令牌
        UsernamePasswordToken token=new UsernamePasswordToken(username,password);
        //一个try 两个catch  try 无异常执行登录        两catch  找不到账号 密码错误
        try {
                 subject.login(token);
            /*HttpServletRequest httpServletRequest= WebUtils.toHttp(request);
            HttpSession session=httpServletRequest.getSession();*/
                 return  "index";//未抛出异常 登录成功
        }catch (UnknownAccountException unknownAccountException){
            //账号未找到异常
            model.addAttribute("msg","账号未找到");
            return "login";
        }catch (IncorrectCredentialsException incorrectCredentialsException){
            //密码错误异常
            model.addAttribute("msg","密码错误");
            return "login";
        }

    }

自定义realm:

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //执行认证
        //当前的令牌 和 controller里面的令牌未同一个令牌
        UsernamePasswordToken usernamePasswordToken= (UsernamePasswordToken) authenticationToken;
        //查询数据库
        SysUser sysUser = userService.selectUser(usernamePasswordToken.getUsername());
        if (sysUser==null){
        //用户名查询为空 账号错误 返回为空 controller登录逻辑 抛出空异常
            return  null;
        }
        //密码认证shiro来做
        return  new SimpleAuthenticationInfo(sysUser,sysUser.getUserPassword(),"");
    }

5.授权

mapper层: public List selectUrl(@Param(“userName”) String userName); 5表联查 查询出账号所对应能访问的url地址

@Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //获取认证时传递的资源 第一个参数
        SysUser principal = (SysUser) subject.getPrincipal();
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        //授权
        //获取当前用户的url地址集合
        List<String> list = userService.selectUrl(principal.getUserName());
         for (int i=0;i<list.size();i++){
              info.addStringPermission(list.get(i));
         }
        return info;
    }

6.注销

controller层:调用当前用户的logout方法 Subject subject = SecurityUtils.getSubject(); subject.logout();

7.显示问题(登录 注销同时显示 无权限地址显示等)

shiro配置类:

@Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

页面整合:

<html lang="en" xmlns:th="http://www.thymeleaf.org"  xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">

登录 注销显示:
controller:
将登录信息保存到session

 Session session=subject.getSession();
session.setAttribute("loginUser",token);

注销调用当前对象的logout方法

页面:

<div th:if="${session.loginUser!=null}">
    <a href="/user/logout">登出</a>
</div>

<div th:if="${session.loginUser==null}">
    <a href="/user/login">登录</a>
</div>

不显示无权限的地址
页面:

<div shiro:hasPermission="/user/add">
    <a href="/user/add">add</a>
</div>
<div shiro:hasPermission="/user/update">
    <a href="/user/update">update</a>
</div>
<a href="/user/other">other</a>

8.MD5加密

Md5Hash hash = new Md5Hash(“1”,“admin”,3);
参数:需要加密的字符 加盐(一般为用户名) 迭代次数

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot整合shiro 的相关文章

随机推荐

  • [从零开始学DeepFaceLab-4]: 使用-命令行八大操作步骤-第1步:命令行环境准备

    目录 总体流程 步骤1 命令行环境准备 1 1 命令 1 clear workspace bat 必选 2 预备知识 2 1 根目录结构
  • Beats — Filebeat 自定义标签+多日志采集

    Beats Filebeat 进阶 一 自定义采集数据标签 自定义标签 自定义字段 终端端显示信息 完整的一个 自定义标签 自定义字段的 filebeat采集日志 logstash 引用标签 对索引进行输出 二 Filebeat 采集多个日
  • pandas 中delete、drop函数的用法

    这两个函数是数据处理是比较常用的函数 在这里重点总结一下 为了方便自己的记忆 也可以和大家一起做一下分享 首先看一下drop函数 DataFrame drop labels None axis 0 index None columns No
  • 2022-VS2015-ACE+TAO(7.0.5)+CIAO+OpenDDS 3.16 编译

    ACE TAO 7 0 5 CIAO OpenDDS 3 16 编译 采用ACE TAO 7 0 5 CIAO 3 10 DANCE OpenDDS 3 16 编译构建OpenDDS系统 本文目的尽量简洁说明ACE TAO CIAO DAN
  • 记一次feign文件上传配置引起的 “xx is not a type supported by this encoder.” 错误

    这里先给出正确的配置 不需要额外新增配置编码器 Encoder 网上大部分会让配置一个SpringFormEncoder 会有隐患问题 下面会详细说明 spring 默认的 FeignClientsConfiguration 中的 Page
  • Java二叉树3

    1 给定一个二叉树 找到该树中两个指定节点的最近公共祖先 最近公共祖先的定义为 对于有根树 T 的两个节点 p q 最近公共祖先表示为一个节点 x 满足 x 是 p q 的祖先且 x 的深度尽可能大 一个节点也可以是它自己的祖先 提示 树中
  • SRAM、DRAM、硬盘、ROM、RAM、EPROM、FLASH区别和联系

    SRAM和DRAM的区别和联系 电脑中的内存属于DRAM CPU中的二级缓存属于SRAM 存储原理 RAM Random Access Memory 随机存取存储器 主要的作用就是存储代码和数据供CPU 在需要的时候调用 但是这些数据并不是
  • win7上搭建android开发环境使用appium自动化测试android应用(一)

    如何通过appium在win7上使用android模拟器测试android应用 本编文章参考了大量网络现存文章 并根据自己的实际情况编写 希望对想用appium的初学者能有所帮助 一 为什么选择appium 你不需要以任何方式重新编译或者修
  • Android Socket 服务器本地发送图片给客户端

    第一步服务端 public static void main String arges 服务器发送图片给客户端 new Thread Override public void run System out println 发送图片信息 Se
  • Android Studio 入门笔记 (二) Activity 和 Application 简介

    Activity用于提供可视化用户界面的组件 可以与用户进行交互完成某项任务 例如拨号 拍照 和 发送e mail等 Activity是Android应用程序的基本组成单位 每一个Activity被赋予一个窗口 用于绘制用户界面 一个Act
  • 区块链技术系列(3)- Fabric基础架构原理

    前言 对于区块链方面多技术 我还是建议大家多看英文文档 多利用Google来搜索技术文章 怎么搭建自己专属V P N来访问Google 请看我之前发的文章 新人如何快速搭建自己的个人网站以及自己专属V P N代理 Linux基金会于2015
  • c++Lab-虚函数

    c Lab 虚函数 里氏转换原则 c 的虚函数 虚函数的实现机制 去掉virtual关键字 获取普通函数和虚函数的地址 机制 里氏转换原则 原文是派生的子类可以用于直接替代其基类 这个是一个很有意思也很常用的原则 当然也很重要 一般在面向对
  • NBIOT连接阿里云控制台(MQTT连接阿里云控制台)

    首先使用MQTT工具连接阿里云平台进行测试之后再使用NBIOT连接控制台 这里主要讲解MQTT连接阿里云的步骤 1 注册或登录阿里云账号 自行前往阿里云官网注册 2 进入物联网界面 首先点击阿里云旁边1位置的选项进入如下界面 找到物联网IO
  • HTTP 请求和 RPC 调用

    rpc字面意思就是远程过程调用 只是对不同应用间相互调用的一种描述 实现方式可以是tcp和http 这里我说一种rpc实现 可以对照dubbo rpc最关键的地方有请求体的封装 响应体的封装以及客户端调用的封装 求体 服务类class 一般
  • 基于Android的视频分享平台的设计与实现

    基于Android的视频分享平台的设计与实现 摘 要 短视频平台是以特定群众为目标的差异化群体定位工具 其利用自身的便捷性可以实现视频的随时拍摄和随时上传 可以产生亚文化圈的萌芽 这种开放便利的特性在吸引了广大用户的同时 也在一定程度上解决
  • 密码学理论11:公钥加密

    公钥加密概述 一方 接收方 生成一对密钥 pk sk 分别称为公钥和私钥 发件人使用公钥加密消息 接收方使用私钥解密生成的密文 当 Alice 得知 Bob 想与她通信时 她可以生成 pk sk 假设她还没有这样做 然后将 pk 明文发送给
  • python读取中编码错误(illegal multibyte sequence )

    读取中文txt文件时 经常会出现 gbk codec can t decode bytes in position 31023 illegal multibyte sequence 主要讲一种情况就是文章中含有utf 8或gbk无法编码的字
  • java学习总结(三),socket和NIO

    Socket 概念 两个程序 进程 通过一个双向通信连接实现数据交换 这个双向连接的一端是一个socket 套接字 分类 1 面向连接 TCP 2 面向无连接 udp 结构 每一个socket都是由ip地址和端口号唯一确定的 生命周期 打开
  • Windows10家庭版使用LxRunOffline工具迁移子系统和docker发行版到其他盘符防止系统盘爆满

    1 下载LxRunOffline工具 2 解压到一个自己平时安装软件的目录 并配置环境变量 重启电脑 打开命令行工具 输入LxRunOffline 如果显示下面的提示证明已经安装成功了 c 2019 Microsoft Corporatio
  • springboot整合shiro

    文章目录 springboot 整合shiro 一 shiro是什么 二 与springboot的整合 1 前期准备 2 ShiroConfiger配置类 3 过滤 拦截 4 认证 5 授权 6 注销 7 显示问题 登录 注销同时显示 无权