SpringBoot整合Shiro

2023-05-16

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。相比较Spring Security,shiro有小巧、简单、易上手等的优点。所以很多框架都在使用shiro。

Shiro包含了三个核心组件:Subject, SecurityManager 和 Realms。

  • Subject代表了当前用户的安全操作。
  • SecurityManager则管理所有用户的安全操作。它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
  • Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。

下面通过示例来演示SpringBoot如何来整合Shiro

1、创建项目ShiroDemo
这里写图片描述

2、配置POM,添加SpringBoot以及Shiro依赖

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
  </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.25</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>0.2.23</version>
    </dependency>
    <!-- shiro权限控制框架 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
  </dependencies>

3、编写MyShiroRealm类,实现AuthorizingRealm接口

public class MyShiroRealm extends AuthorizingRealm {

    /**
     * 授权用户权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        //获取用户
        User user = (User)SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo();
        //获取用户角色
        Set<String> roleSet = new HashSet<String>();
        roleSet.add("100002");
        info.setRoles(roleSet);

        //获取用户权限
        Set<String> permissionSet = new HashSet<String>();
        permissionSet.add("权限添加");
        permissionSet.add("权限删除");
        info.setStringPermissions(permissionSet);


        return info;
    }

    /**
     * 验证用户身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken authcToken) throws AuthenticationException {

        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        String username = token.getUsername();
        String password = String.valueOf(token.getPassword());

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("nickname", username);
        //密码进行加密处理  明文为  password+name
        String paw = password+username;
        String pawDES = MyDES.encryptBasedDes(paw);
        map.put("pswd", pawDES);

        User user = new User();
        user.setId("112222");
        user.setUsername(username);
        user.setPassword(pawDES);


        return new SimpleAuthenticationInfo(user, password, getName());
    }

}

4、实现ShiroConfiguration

@Configuration
public class ShiroConfiguration {

    /**
     * ShiroFilterFactoryBean 处理拦截资源文件问题。
     * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
     * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager
     *
     * Filter Chain定义说明 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过
     * 3、部分过滤器可指定参数,如perms,roles
     *
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/index");
        // 未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");

        //自定义拦截器
        Map<String, Filter> filtersMap = new LinkedHashMap<String, Filter>();
        //限制同一帐号同时在线的个数。
        //filtersMap.put("kickout", kickoutSessionControlFilter());
        shiroFilterFactoryBean.setFilters(filtersMap);

        // 权限控制map.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        // 配置不会被拦截的链接 顺序判断
        // 配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
        // 从数据库获取动态的权限
        // filterChainDefinitionMap.put("/add", "perms[权限添加]");
        // <!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        //logout这个拦截器是shiro已经实现好了的。
        // 从数据库获取
        /*List<SysPermissionInit> list = sysPermissionInitService.selectAll();

        for (SysPermissionInit sysPermissionInit : list) {
            filterChainDefinitionMap.put(sysPermissionInit.getUrl(),
                    sysPermissionInit.getPermissionInit());
        }*/

        shiroFilterFactoryBean
                .setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        securityManager.setRealm(myShiroRealm());
        // 自定义缓存实现 使用redis
        //securityManager.setCacheManager(cacheManager());
        // 自定义session管理 使用redis
        //securityManager.setSessionManager(sessionManager());
        //注入记住我管理器;
        securityManager.setRememberMeManager(rememberMeManager());
        return securityManager;
    }

    public MyShiroRealm myShiroRealm(){
        return new MyShiroRealm();
    }

    /**
     * cookie对象;
     * @return
     */
    public SimpleCookie rememberMeCookie(){
       //这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
       SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
       //<!-- 记住我cookie生效时间30天 ,单位秒;-->
       simpleCookie.setMaxAge(2592000);
       return simpleCookie;
    }

    /**
     * cookie管理对象;记住我功能
     * @return
     */
    public CookieRememberMeManager rememberMeManager(){
       CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
       cookieRememberMeManager.setCookie(rememberMeCookie());
       //rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
       cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));
       return cookieRememberMeManager;
    }

}

5、编写LoginController类测试Shiro

@RestController
public class LoginController {

    @RequestMapping(value="/login",method=RequestMethod.POST)
    public String login(String username, String password,String vcode,Boolean rememberMe){
        System.out.println(username);
        UsernamePasswordToken token = new UsernamePasswordToken(username, password,rememberMe);
        SecurityUtils.getSubject().login(token);

        return "loginSuccess";
    }

    @RequestMapping(value="/index",method=RequestMethod.GET)
    public String home(){
        Subject subject = SecurityUtils.getSubject();
        User principal = (User)subject.getPrincipal();

        return "Home";
    }

}
  • 在postman中访问http://127.0.0.1:8080/login,Body中携带参数以及值
    这里写图片描述

  • 访问http://127.0.0.1:8080/index,从Subject中获取登录后的用户信息
    这里写图片描述

源码:http://download.csdn.net/download/u012343297/10177427

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

SpringBoot整合Shiro 的相关文章

随机推荐

  • java 8 根据map 字段值 去重

    java 8 根据map 字段值 去重 span class token class name List span span class token generics span class token punctuation lt span
  • java 8 去重

    span class token comment 取差集 span span class token class name List span span class token generics span class token punct
  • 解读程序员的武侠世界,顶级程序员是内外兼修的大侠,那么你呢?

    在漫天的星河中 xff0c 有这样一颗星 xff0c 他朴实无华 xff0c 却又熠熠生辉 xff0c 照亮了无数人的人生 他就是金庸先生 随着一代大侠的驾鹤西去 xff0c 飞雪连天射白鹿 xff0c 笑书神侠倚碧鸳 xff0c 成为绝响
  • Eclipse使用入门教程

    Eclipse使用入门教程 说起java的IDE xff0c 朗朗上口的无非是Eclipse了 xff0c 假若能熟练Eclipse xff0c 对于我们编写java程序会起到事半功倍的效果 xff0c 大大提高我们工作效率 因此本篇博文
  • Win7 + Ubuntu16.04 双系统安装

    之前安装win7 43 Ubuntu14 04双系统 xff0c 后来换成win10用了一段时间后觉得有些卡 xff0c 而且装双系统装了几次都成功 xff0c 所以又换回了win7系统 xff0c 并重新安装了win7 43 Ubuntu
  • 双系统Ubuntu 引导修复(Boot Repair)

    安装完双系统 xff0c 如果在使用过程中不小心删除了Ubuntu引导向 xff0c 则会导致开机后无法选择进入Ubuntu系统 或者当我们重装了windows系统后 xff0c 也会发现原来的Ubuntu引导不见了 xff0c 当出现这两
  • 数据库为何要有复合主键(多主键)

    最近学习一点数据库的基本知识 xff0c 被一个问题困惑了许久 xff1a 主键是唯一的索引 xff0c 那么为何一个表可以创建多个主键呢 xff1f 其实 主键是唯一的索引 这话有点歧义的 举个例子 xff0c 我们在表中创建了一个ID字
  • @JSONField 注解详解和应用

    讲到 64 JSONField 注解 xff0c 就不得不提到Alibaba 开源的fasejson fastjson是目前java语言中最快的json库 xff0c 比自称最快的jackson速度要快 xff0c 第三方独立测试结果看这里
  • 外部访问docker容器(docker run -p/-P 指令)

    容器中可以运行一些网络应用 xff0c 要让外部也可以访问这些应用 xff0c 可以通过 P xff08 大写 xff09 或 p xff08 小写 xff09 参数来指定端口映射 xff08 1 xff09 当使用 P 标记时 xff0c
  • 解决Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题

    LocalDate LocalTime LocalDateTime 是Java 8开始提供的时间日期API xff0c 主要用来优化Java 8以前对于时间日期的处理操作 然而 xff0c 我们在使用Spring Boot或使用Spring
  • gcc 编译选项

    原来 Os相当于 O2 5 是使用了所有 O2的优化选项 xff0c 但又不缩减代码尺寸的方法 ffunction sections fdata sections Place each function or data item into
  • RYU功能开发(一)从simple switch开始

    对于任意一款控制器 xff0c 想要快速了解其开发机制 xff0c 从转发模块入手无疑是最佳的学习方式 RYU通过App的形式提供了一系列功能模块 xff0c 其中包括使用了OpenFlow作为控制协议的二层交换机控制模块simple sw
  • arm-linux-gcc交叉工具链

    Linux ARM交叉编译工具链制作过程 一 下载源文件 源代码文件及其版本与下载地址 xff1a Binutils 2 19 tar bz2 Index of gnu binutils gcc 4 4 4 tar bz2 Index of
  • 我使用过的Linux命令之cal - 显示日历

    我使用过的Linux命令之cal 显示日历 本文链接 xff1a http codingstandards iteye com blog 807962 xff08 转载请注明出处 xff09 用途说明 cal命令可以用来显示公历 xff08
  • 驼峰式与下划线命名规则

    在实际代码开发过程中 xff0c 代码编写格式清晰与否不仅决定了自己的代码编写与维护成本 xff0c 也直接影响到项目的开发进度 编码中常用的有驼峰法和下划线两种编码格式 xff0c 其中驼峰法常用在面向对象的高层语言中 xff0c 下划线
  • 全图文分析:如何利用Google的protobuf,来思考、设计、实现自己的RPC框架

    文章目录 一 前言二 RPC 基础概念1 RPC 是什么 xff1f 2 需要解决什么问题 xff1f 3 有哪些开源实现 xff1f 三 protobuf 基本使用1 基本知识2 使用步骤 四 libevent1 libevent 简介2
  • 针对vue的配置文件

    针对vue的配置文件 我们在根目录下创建一个 vue config js 文件 xff0c 将下方配置下去 module exports 61 区分打包环境与开发环境 process env NODE ENV 61 61 61 39 pro
  • Linux | LVM | 对比三种逻辑卷(Logic Volume)

    概述 为了满足在性能和冗余等方面的需求 xff0c LVM支持了下面三种Logic Volume xff1a Linear Logic Volume 线性逻辑卷Striped Logic Volume 条带化逻辑卷Mirror Logic
  • MySql ERROR 1129

    ERROR 1129 HY000 Host 39 mysql02 39 is blocked because of many connection errors unblock with 39 mysqladmin flush hosts
  • SpringBoot整合Shiro

    Apache Shiro是一个强大且易用的Java安全框架 执行身份验证 授权 密码学和会话管理 相比较Spring Security xff0c shiro有小巧 简单 易上手等的优点 所以很多框架都在使用shiro Shiro包含了三个