当前位置:

首页 > 编程开发 > 怎么用Springboot快速整合shiro安全框架

怎么用Springboot快速整合shiro安全框架

咱们先来普及一下什么是shiro,shiro原名ApacheShiro是一个Java的安全(权限)框架。Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以完成,认证,授权,加密,会话管理,Web集成,缓存等高级应用。如图看shiro的功能和架构图:话不多说,Springboot整合shiro,咱们直接上代码pom.xml文件4.0.0org.springframework.bootspring-boot-starter-parent2.6

本文目录

    咱们先来普及一下什么是shiro,shiro原名Apache Shiro 是一个Java 的安全(权限)框架。Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以完成,认证,授权,加密,会话管理,Web集成,缓存等高级应用。如图看shiro的功能和架构图:

    怎么用Springboot快速整合shiro安全框架

    怎么用Springboot快速整合shiro安全框架

    话不多说,Springboot整合shiro,咱们直接上代码

    pom.xml文件

    
    
        4.0.0
        
            org.springframework.boot
            spring-boot-starter-parent
            2.6.11
             
        
        com.example
        demo02
        0.0.1-SNAPSHOT
        demo02
        demo02
    
        
            1.8
        
    
        
            
                org.apache.shiro
                shiro-spring
                1.4.1
            
    
            
                org.mybatis.spring.boot
                mybatis-spring-boot-starter
                2.1.0
            
            
                mysql
                mysql-connector-java
               8.0.31
            
            
            
                log4j
                log4j
                1.2.17
            
            
            
                com.alibaba
                druid
                1.1.12
            
    
            
                org.projectlombok
             lombok
               1.18.18
                compile
            
    
    
            
                org.springframework.boot
                spring-boot-starter-thymeleaf
            
            
                org.thymeleaf
                thymeleaf
            
            
                org.thymeleaf.extras
                thymeleaf-extras-java8time
            
            
                org.springframework.boot
                spring-boot-starter-web
            
    
            
                org.springframework.boot
                spring-boot-starter-test
                test
            
    
            
                com.github.theborakompanioni
                thymeleaf-extras-shiro
                2.0.0
            
    
    
        
    
        
            
                
                    org.apache.maven.plugins
                    maven-compiler-plugin
                    3.8.1
                    
                        1.8
                        1.8
                        UTF-8
                    
                
                
                    org.springframework.boot
                    spring-boot-maven-plugin
                
            
        
    
    

    然后我们建立一个数据库 /*
    Navicat MySQL Data Transfer

    Source Server :
    Source Server Version : 80030
    Source Host : localhost:3306
    Source Database : mybatis

    Target Server Type : MYSQL
    Target Server Version : 80030
    File Encoding : 65001

    Date: 2023-03-14 18:00:05
    */

    SET FOREIGN_KEY_CHECKS=0;

    – Table structure for user

    DROP TABLE IF EXISTS user;
    CREATE TABLE user (
    id int NOT NULL AUTO_INCREMENT,
    name varchar(255) DEFAULT NULL,
    pwd varchar(255) DEFAULT NULL,
    perms varchar(100) DEFAULT NULL,
    PRIMARY KEY (id)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

    – Records of user

    INSERT INTO user VALUES (‘1’, ‘qin’, ‘d1b129656359e35e95ebd56a63d7b9e0’, ‘user:add’);
    INSERT INTO user VALUES (‘2’, ‘hai’, ‘123’, ‘user:insert’);
    INSERT INTO user VALUES (‘3’, ‘root’, ‘d1b129656359e35e95ebd56a63d7b9e0’, ‘user:update’);

    application.yml文件

    spring:
       datasource:
          username: xxxx
          password: xxxxxxxxxxxx
          url: jdbc:mysql://localhost:3306/mybatis
          driver-class-name: com.mysql.cj.jdbc.Driver
          type: com.alibaba.druid.pool.DruidDataSource
    mybatis:
       mapper-locations: classpath:mapper/*tat.slowSqlMillis=500

    controller层MyController类

    package com.example.demo02.controller;
    
    import lombok.extern.slf4j.Slf4j;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.subject.Subject;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    @Slf4j
    public class MyController {
    
        @RequestMapping("/")
        public  String toIndex(Model model){
            model.addAttribute("msg","hello,shiro");
            return "login";
    
        }
    
    
        @RequestMapping("/user/add")
        public String add(){
            return "user/add";
        }
    
        @RequestMapping("/user/update")
        public String update(){
            return  "user/update";
        }
        @RequestMapping("/toLogin")
        public String toLogin(){
            return "login";
        }
    
        @RequestMapping("/noauth")
        @ResponseBody
        public String noAuth(){
            return "未经授权不能访问此页面";
        }
    
        //登录操作
        @RequestMapping("/login")
        public String login(String username, String password, @RequestParam(defaultValue = "false")boolean rememberMe,Model model){
    //使用shiro,编写认证操作
    //1. 获取Subject
            Subject subject = SecurityUtils.getSubject();
    //2. 封装用户的数据
            UsernamePasswordToken token = new UsernamePasswordToken(username, password,rememberMe);
    //3. 执行登录的方法,只要没有异常就代表登录成功!
            try {
                subject.login(token); //登录成功!返回首页
                System.out.println("输出认证成功跳转页面");
    
    
                return "index";
            } catch (UnknownAccountException e) { //用户名不存在
                model.addAttribute("msg","用户名不存在");
                return "login";
            } catch (IncorrectCredentialsException e) { //密码错误
                model.addAttribute("msg","密码错误");
                return "login";
            }
        }
    }

    pojo层User

    package com.example.demo02.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private int id;
        private String name;
        private String pwd;
        private String perms;
    }

    config层配置两个类
    第一个类ShiroConfig

    package com.example.demo02.config;
    
    import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    //声明为配置类
    @Configuration
    public class ShiroConfig {
        //创建 ShiroFilterFactoryBean
        @Bean
        public ShiroFilterFactoryBean
        getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    //设置安全管理器
            shiroFilterFactoryBean.setSecurityManager(securityManager);
    /*
    添加Shiro内置过滤器,常用的有如下过滤器:
    anon: 无需认证就可以访问
    authc: 必须认证才可以访问
    user: 如果使用了记住我功能就可以直接访问
    perms: 拥有某个资源权限才可以访问
    role: 拥有某个角色权限才可以访问
    *
    /
    
     */
            //进行一个拦截
        Map filterMap = new LinkedHashMap();
    //    filterMap.put("/user/add","authc");
    //    filterMap.put("/user/update","authc");
            //授权
    //        filterMap.put("/user/add","perms[user:add]"); //大家记得注意顺序!
    
            filterMap.put("/user/add","perms[user:add]");
            filterMap.put("/user/update","perms[user:update]");
            filterMap.put("/user/*","authc");
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
    
    
    
    
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        //未授权页面
            shiroFilterFactoryBean.setUnauthorizedUrl("/noauth");
            return shiroFilterFactoryBean;
    }
        //创建 DefaultWebSecurityManager
        @Bean(name = "securityManager")
        public DefaultWebSecurityManager
        getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            //2创建加密对象,设置相关属性
            HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
            //2.1采用md5加密
            matcher.setHashAlgorithmName("md5");
            //2.2迭代加密次数
            matcher.setHashIterations(3);
            //3将加密对象存储到myRealm中
            userRealm.setCredentialsMatcher(matcher);
    
    
    //关联Realm
            securityManager.setRealm(userRealm);
            return securityManager;
        }
        //创建 realm 对象
        @Bean
        public UserRealm userRealm(){
            return new UserRealm();
        }
    
        //配置ShiroDialect:方言,用于 thymeleaf 和 shiro 标签配合使用
        @Bean
        public ShiroDialect getShiroDialect(){
            return new ShiroDialect();
        }
    }

    UserRealm

    package com.example.demo02.config;
    
    
    import com.example.demo02.pojo.User;
    import com.example.demo02.service.UserService;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.ByteSource;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import java.util.List;
    
    //自定义得UserRaelm
    public class UserRealm extends AuthorizingRealm {
    
        @Autowired
        UserService userService;
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            System.out.println("执行了=》授权doGetAuthorizationInfo");
            SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
    
    //        info.addStringPermission("user:update");
            info.addStringPermission("user:add");
            //拿到当前用户登陆对象
            Subject subject= SecurityUtils.getSubject();
            User currentUser= (User) subject.getPrincipal();//拿到User对象
             info.addStringPermission(currentUser.getPerms());//设置当前用户对象
    
            return info;
        }
    
        //执行认证逻辑
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("执行了=>认证逻辑AuthenticationToken");
    //假设数据库的用户名和密码
    //        String name = "root";
    //        String password = "123456";
    
    
    //1.判断用户名
            UsernamePasswordToken userToken = (UsernamePasswordToken)token;
           //连接真实的数据库
            User user= userService.queryUserByName(userToken.getUsername());
    //
            if(user==null){
                return  null;
            }
            Subject subject = SecurityUtils.getSubject();
            subject.getSession().setAttribute("loginUser",user);
    
    
    //2. 验证密码,我们可以使用一个AuthenticationInfo实现类SimpleAuthenticationInfo
    // shiro会自动帮我们验证!重点是第二个参数就是要验证的密码!
            return new SimpleAuthenticationInfo(user, user.getPwd(),ByteSource.Util.bytes("salt"),"");
    //        if(user !=null){
    //            AuthenticationInfo info = new SimpleAuthenticationInfo(
    //                    token.getPrincipal(),
    //                    user.getPwd(),
    //                    ByteSource.Util.bytes("salt"),
    //                    token.getPrincipal().toString()
    //            );
    //            return info;
    //        }
    //        return null;
    
    
    
    
        }
    }

    service层
    先是类UserServiceImpl

    package com.example.demo02.service;
    
    
    import com.example.demo02.mapper.UserMapper;
    import com.example.demo02.pojo.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        UserMapper userMapper;
        @Override
        public User queryUserByName(String name) {
            return userMapper.queryUserByName(name);
        }
    }

    再是接口UserService

    package com.example.demo02.service;
    
    import com.example.demo02.pojo.User;
    
    public interface UserService {
        public User queryUserByName(String name);
    }

    mapper层
    接口Usermapper

    package com.example.demo02.mapper;
    
    import com.example.demo02.pojo.User;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    import org.springframework.stereotype.Repository;
    
    @Repository
    //@Mapper
    public interface UserMapper {
        @Select("select * from user where name=#{name}")
        public User queryUserByName(@Param("name") String name);
    }

    再就是前端resources里面的static和templates

    后端实现鉴权图

    怎么用Springboot快速整合shiro安全框架

    存入数据库的数据为加密文件

    怎么用Springboot快速整合shiro安全框架

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。