Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro。

今天松哥就来和大家聊聊 Spring Boot 整合 Shiro 的话题!

一般来说,Spring Security 和 Shiro 的比较如下:

  1. Spring Security 是一个重量级的安全管理框架;Shiro 则是一个轻量级的安全管理框架
  2. Spring Security 概念复杂,配置繁琐;Shiro 概念简单、配置简单
  3. Spring Security 功能强大;Shiro 功能简单

虽然 Shiro 功能简单,但是也能满足大部分的业务场景。所以在传统的 SSM 项目中,一般来说,可以整合 Shiro。

在 Spring Boot 中,由于 Spring Boot 官方提供了大量的非常方便的开箱即用的 Starter ,当然也提供了 Spring Security 的 Starter ,使得在 Spring Boot 中使用 Spring Security 变得更加容易,甚至只需要添加一个依赖就可以保护所有的接口,所以,如果是 Spring Boot 项目,一般选择 Spring Security 。

这只是一个建议的组合,单纯从技术上来说,无论怎么组合,都是没有问题的。

在 Spring Boot 中整合 Shiro ,有两种不同的方案:

  1. 第一种就是原封不动的,将 SSM 整合 Shiro 的配置用 Java 重写一遍。
  2. 第二种就是使用 Shiro 官方提供的一个 Starter 来配置,但是,这个 Starter 并没有简化多少配置。

原生的整合

  • 创建项目

创建一个 Spring Boot 项目,只需要添加 Web 依赖即可:

Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

项目创建成功后,加入 Shiro 相关的依赖,完整的 pom.xml 文件中的依赖如下:


        org.springframework.boot
        spring-boot-starter-web

        org.apache.shiro
        shiro-web
        1.4.0

        org.apache.shiro
        shiro-spring
        1.4.0

  • 创建 Realm

接下来我们来自定义核心组件 Realm:

public class MyRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        if (!"javaboy".equals(username)) {
            throw new UnknownAccountException("账户不存在!");
        }
        return new SimpleAuthenticationInfo(username, "123", getName());
    }
}

在 Realm 中实现简单的认证操作即可,不做授权,授权的具体写法和 SSM 中的 Shiro 一样,不赘述。这里的认证表示用户名必须是 javaboy ,用户密码必须是 123 ,满足这样的条件,就能登录成功!

  • 配置 Shiro

接下来进行 Shiro 的配置:

@Configuration
public class ShiroConfig {
    @Bean
    MyRealm myRealm() {
        return new MyRealm();
    }

    @Bean
    SecurityManager securityManager() {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(myRealm());
        return manager;
    }

    @Bean
    ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(securityManager());
        bean.setLoginUrl("/login");
        bean.setSuccessUrl("/index");
        bean.setUnauthorizedUrl("/unauthorizedurl");
        Map map = new LinkedHashMap<>();
        map.put("/doLogin", "anon");
        map.put("/**", "authc");
        bean.setFilterChainDefinitionMap(map);
        return bean;
    }
}

在这里进行 Shiro 的配置主要配置 3 个 Bean :

  1. 首先需要提供一个 Realm 的实例。
  2. 需要配置一个 SecurityManager,在 SecurityManager 中配置 Realm。
  3. 配置一个 ShiroFilterFactoryBean ,在 ShiroFilterFactoryBean 中指定路径拦截规则等。
  4. 配置登录和测试接口。

其中,ShiroFilterFactoryBean 的配置稍微多一些,配置含义如下:

  • setSecurityManager 表示指定 SecurityManager。
  • setLoginUrl 表示指定登录页面。
  • setSuccessUrl 表示指定登录成功页面。
  • 接下来的 Map 中配置了路径拦截规则,注意,要有序。

这些东西都配置完成后,接下来配置登录 Controller:

@RestController
public class LoginController {
    @PostMapping("/doLogin")
    public void doLogin(String username, String password) {
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(new UsernamePasswordToken(username, password));
            System.out.println("登录成功!");
        } catch (AuthenticationException e) {
            e.printStackTrace();
            System.out.println("登录失败!");
        }
    }
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
    @GetMapping("/login")
    public String  login() {
        return "please login!";
    }
}

测试时,首先访问 /hello 接口,由于未登录,所以会自动跳转到 /login 接口:

Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

然后调用 /doLogin 接口完成登录:

Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

再次访问 /hello 接口,就可以成功访问了:

Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

使用 Shiro Starter

上面这种配置方式实际上相当于把 SSM 中的 XML 配置拿到 Spring Boot 中用 Java 代码重新写了一遍,除了这种方式之外,我们也可以直接使用 Shiro 官方提供的 Starter 。

  • 创建工程,和上面的一样

创建成功后,添加 shiro-spring-boot-web-starter ,这个依赖可以代替之前的 shiro-webshiro-spring 两个依赖,pom.xml 文件如下:


        org.springframework.boot
        spring-boot-starter-web

        org.apache.shiro
        shiro-spring-boot-web-starter
        1.4.0

  • 创建 Realm

这里的 Realm 和前面的一样,我就不再赘述。

  • 配置 Shiro 基本信息

接下来在 application.properties 中配置 Shiro 的基本信息:

shiro.sessionManager.sessionIdCookieEnabled=true
shiro.sessionManager.sessionIdUrlRewritingEnabled=true
shiro.unauthorizedUrl=/unauthorizedurl
shiro.web.enabled=true
shiro.successUrl=/index
shiro.loginUrl=/login

配置解释:

  1. 第一行表示是否允许将sessionId 放到 cookie 中
  2. 第二行表示是否允许将 sessionId 放到 Url 地址拦中
  3. 第三行表示访问未获授权的页面时,默认的跳转路径
  4. 第四行表示开启 shiro
  5. 第五行表示登录成功的跳转页面
  6. 第六行表示登录页面

  7. 配置 ShiroConfig

@Configuration
public class ShiroConfig {
    @Bean
    MyRealm myRealm() {
        return new MyRealm();
    }
    @Bean
    DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(myRealm());
        return manager;
    }
    @Bean
    ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
        definition.addPathDefinition("/doLogin", "anon");
        definition.addPathDefinition("/**", "authc");
        return definition;
    }
}

这里的配置和前面的比较像,但是不再需要 ShiroFilterFactoryBean 实例了,替代它的是 ShiroFilterChainDefinition ,在这里定义 Shiro 的路径匹配规则即可。

这里定义完之后,接下来的登录接口定义以及测试方法都和前面的一致,我就不再赘述了。大家可以参考上文。

总结

本文主要向大家介绍了 Spring Boot 整合 Shiro 的两种方式,一种是传统方式的 Java 版,另一种则是使用 Shiro 官方提供的 Starter,两种方式,不知道大家有没有学会呢?

本文案例,我已经上传到 GitHub ,欢迎大家 star:https://github.com/lenve/javaboy-code-samples

关于本文,有问题欢迎留言讨论。

Original: https://www.cnblogs.com/lenve/p/12321204.html
Author: 江南一点雨
Title: Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/540499/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Activiti6.0集成SpringBoot2.1.6+idea详细基础开发

    开发环境:JDK1.8+idea工具+maven 首先idea下载插件File->settings->plugins->Marketplace 直接搜索actiB…

    Java 2023年5月29日
    070
  • java多线程基础学习

    一、多线程概述 1.1、进程和线程的概念 1.1.1、进程 1.1.2、线程 1.2、线程创建的方法 1.2.1、继承Thread类 1.2.2、重写Runnable接口 1.2….

    Java 2023年6月16日
    076
  • MySQL中的WHERE和HAVING

    使用 GROUP BY语句时,有时会同时使用 WHERE和 HAVING,常常会因为搞不清楚要用哪个而写错,这里记录一下 TL;NRs WEHRE语句必须在 GROUP BY之前,…

    Java 2023年6月9日
    063
  • linux常用命令

    linux开放指定端口命令 1、开启防火墙 systemctl start firewalld查看防火墙状态systemctl status firewalld2、开放指定端口fi…

    Java 2023年6月16日
    067
  • 设计模式——单例模式

    引言 今天来谈谈设计模式中的单例模式,温故知新,以免生疏。 软件设计领域的四位世界级大师Gang Of Four (GoF):Erich Gamma,Richard Helm,Ra…

    Java 2023年6月8日
    0106
  • 公众号资料分享

    在公众号分享两份资料一份是面试资料整理,面试资料针对Java方向,从JVM虚拟机到机器学习,云计算都有涉及,虽然机器学习有些内容比较简单,但是整体的知识框架还是列出来了,总结的非常…

    Java 2023年5月30日
    061
  • nginx 基本操作

    nginx 是什么 nginx 是轻量、高性能的网页服务器,相较 Apache 占有内存小。 下载 https://nginx.org/en/download.html 默认根目录…

    Java 2023年5月30日
    078
  • 乐观锁与悲观锁

    总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后…

    Java 2023年6月9日
    078
  • Java的网络通信

    网络通信概述 网络通信编程的三要素:①IP地址 ②端口号 ③协议 IP常用命令 说明 ipconfig 查看本机ip地址 ping IP地址 检查网络是否连通 本机ip:127.0…

    Java 2023年6月9日
    068
  • springcloud alibaba 集成 nacos注册中心配置使用

    pom <span class="hljs-tag"><<span class="hljs-name">pro…

    Java 2023年6月7日
    073
  • 创建SpringCloud项目

    一、创建父工程 1、选择maven,直接–>next 2、填写项目相关的信息,next 3、填写项目名和项目位置–>finish 4、修改pom…

    Java 2023年5月30日
    098
  • MySQL中的事务和MVCC

    本篇博客参考掘金小册——MySQL 是怎样运行的:从根儿上理解 MySQL 以及极客时间——MySQL实战45讲。 虽然我们不是DBA,可能对数据库没那么了解,但是对于数据库中的索…

    Java 2023年6月5日
    089
  • IDEA集成MyBatis Generator 插件 详解

    1、修改maven的pom文件 只需要将如下依赖添加到pom.xml文件中即可。(注意此处是以plugin的方式,放在 <plugins></plugins&gt…

    Java 2023年5月30日
    073
  • oracle踩坑

    好久没有写博客了,就分享一些乱七八糟的东西吧! 1.oracle递归查询 大家应该使用有的时候会使用递归查询数据库菜单的吧,比如下面这样的(偷的图)( ̄▽ ̄)ノ 这种一般是业务管理…

    Java 2023年6月6日
    096
  • 什么是计算机?

    计算机 组成:硬件+软件能按程序运行,自动、告诉处理海量数据的现代化智能电子设备。应用:科学计算、数据处理、自动控制、计算机辅助设计、人工智能、网络(互联网、自己的计算机就是网络的…

    Java 2023年6月6日
    053
  • 用两行代码实现重试功能,spring-retry真是简单而优雅

    最近做的一个需求,需要调用第三方接口。正常情况下,接口的响应是符合要求的,只有在网络抖动等极少数的情况下,会存在超时情况。因为是小概率事件,所以一次超时之后,进行一次重试操作应该就…

    Java 2023年6月5日
    081
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球