SpringBoot浅析安全管理之Shiro框架

目录
  • Shiro 简介
  • 整合 Shiro
    • 1. 创建项目
    • 2. Shiro基本配置
    • 3. 测试

Shiro 简介

Apache Shiro 是一个开源的轻量级的 Java 安全框架,它提供身份验证、授权、密码管理以及会话管理等功能。相对于 Spring Security ,Shiro 框架更加直观、易用,同时也能提供健壮的安全性。

在传统的 SSM 框架中,手动整合 Shiro 的配置步骤还是比较多的,针对 Spring Boot ,Shiro 官方提供了 shiro-spring-boot-web-starter 用来简化 Shiro 在 Spring Boot 中的配置。

整合 Shiro

1. 创建项目

首先创建一个普通的 Spring Boot Web 项目,添加 Shiro 依赖以及页面模板依赖

<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring-boot-web-starter</artifactId>
  <version>1.4.0</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
  <groupId>com.github.theborakompanioni</groupId>
  <artifactId>thymeleaf-extras-shiro</artifactId>
  <version>2.0.0</version>
</dependency>

这里不需要添加 spring-boot-starter-web 依赖,shiro-spring-boot-web-starter 中已经依赖了 spring-boot-starter-web 。同时,此处使用 Thymeleaf 模板,为了在 Thymeleaf 使用 shiro 标签,加入了 thymeleaf-extras-shiro 依赖。

2. Shiro基本配置

在 application.properties 中配置 Shiro 的基本信息

# 开启 Shiro 配置,默认为 true
shiro.enabled=true
# 开启 Shiro Web 配置,默认为 true
shiro.web.enabled=true
# 配置登录地址,默认为 /login.jsp
shiro.loginUrl=/login
# 配置登录成功的地址,默认为 /
shiro.successUrl=/index
# 未获授权默认跳转地址
shiro.unauthorizedUrl=/unauthorized
# 是否允许通过 URL 参数实现会话跟踪,如果网站支持 Cookie,可以关闭此选项,默认为 true
shiro.sessionManager.sessionIdUrlRewritingEnabled=true
# 是否允许通过 Cookie 实现会话跟踪,默认为 true
shiro.sessionManager.sessionIdCookieEnabled=true

然后在 Java 代码中配置 Shiro ,提供两个最基本的 Bean 即可

@Configuration
public class ShiroConfig {
    @Bean
    public Realm realm() {
        TextConfigurationRealm realm = new TextConfigurationRealm();
        realm.setUserDefinitions("sang=123,user\n admin=123,admin");
        realm.setRoleDefinitions("admin=read,write\n user=read");
        return realm;
    }
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition =
                new DefaultShiroFilterChainDefinition();
        chainDefinition.addPathDefinition("/login", "anon");
        chainDefinition.addPathDefinition("/doLogin", "anon");
        chainDefinition.addPathDefinition("/logout", "logout");
        chainDefinition.addPathDefinition("/**", "authc");
        return chainDefinition;
    }
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
}

代码解释:

  • 这里提供两个关键的 Bean ,一个是 Realm,另一个是 ShiroFilterChainDefinition 。至于 ShiroDialect 则是为了支持在 Thymeleaf 中使用 Shiro 标签,如果不在 Thymeleaf 中使用 Shiro 标签,那么可以不提供 ShiroDialect
  • Realm 可以是自定义的 Realm,也可以是 Shiro 提供的 Realm,简单起见,此处没有配置数据库连接,直接配置了两个用户:sang/123 和 admin/123 ,分别对应角色 user 和 admin。
  • ShiroFilterChainDefinition Bean 中配置了基本的过滤规则 ,“/login” 和 “/doLogin”,可以匿名访问,“/logout”是一个注销登录请求,其余请求则都需要认证后才能访问

然后配置登录接口以及页面访问接口

@Controller
public class UserController {
    @PostMapping("/doLogin")
    public String doLogin(String username, String password, Model model) {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (AuthenticationException e) {
            model.addAttribute("error", "用户名或密码输入错误!");
            return "login";
        }
        return "redirect:/index";
    }
    @RequiresRoles("admin")
    @GetMapping("/admin")
    public String admin() {
        return "admin";
    }
    @RequiresRoles(value = {"admin", "user"}, logical = Logical.OR)
    @GetMapping("/user")
    public String user() {
        return "user";
    }
}

代码解释:

  • 在 doLogin 方法中,首先构建一个 UsernamePasswordToken 实例,然后获取一个 Subject 对象并调用该对象中的 login 方法执行登录操作,在登录操作执行过程中,当有异常抛出时,说明登录失败,携带错误信息返回登录视图;当登录成功时,则重定向到“/index”
  • 接下来暴露两个接口“/admin”和“/user”,对于“/admin”接口,需要具有 admin 角色才可以访问;对于“/user”接口,具备 admin 角色 和 user角色其中任意一个即可访问

对于其他不需要角色就能访问的接口,直接在 WebMvc 中配置即可

@Configuration
public class WebMvcConfig implements WebMvcConfigurer{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/index").setViewName("index");
        registry.addViewController("/unauthorized").setViewName("unauthorized");
    }
}

接下来创建全局异常处理器进行全局异常处理,此处主要是处理授权异常

@ControllerAdvice
public class ExceptionController {
    @ExceptionHandler(AuthorizationException.class)
    public ModelAndView error(AuthorizationException e) {
        ModelAndView mv = new ModelAndView("unauthorized");
        mv.addObject("error", e.getMessage());
        return mv;
    }
}

当用户访问未授权的资源时,跳转到 unauthorized 视图中,并携带出错误信息。

配置完成后,最后在 resources/templates 目录下创建 5 个 HTML 页面进行测试。

(1)index.html

<!DOCTYPE html>
<html lang="en" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>Hello, <shiro:principal/></h3>
<h3><a href="/logout" rel="external nofollow" >注销登录</a></h3>
<h3><a shiro:hasRole="admin" href="/admin" rel="external nofollow" >管理员页面</a></h3>
<h3><a shiro:hasAnyRoles="admin,user" href="/user" rel="external nofollow" >普通用户页面</a></h3>
</body>
</html>

(2)login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <form action="/doLogin" method="post">
        <input type="text" name="username"><br>
        <input type="password" name="password"><br>
        <div th:text="${error}"></div>
        <input type="submit" value="登录">
    </form>
</div>
</body>
</html>

(3)user.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>普通用户页面</h1>
</body>
</html>

(4)admin.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>管理员页面</h1>
</body>
</html>

(5)unauthorized.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <h3>未获授权,非法访问</h3>
    <h3 th:text="${error}"></h3>
</div>
</body>
</html>

3. 测试

启动项目,访问登录页面,使用 sang/123 登录

注意:由于 sang 用户不具备 admin 角色,因此登录成功后的页面没有前往管理员页面的超链接。

然后使用 admin/123 登录。

如果用户使用 sang 登录,然后去访问:http://localhost:8080/admin,会跳转到未授权页面

以上通过一个简单的案例展示了如何在 Spring Boot 中整合 Shiro 以及如何在 Thymeleaf 中使用 Shiro 标签,一旦整合成功,接下来 Shiro 的用法就和原来的一模一样。此处主要将 Spring Boot 整合 Shiro,对于 Shiro 的其它用法,可以参考 Shiro 官方文档。

到此这篇关于SpringBoot浅析安全管理之Shiro框架的文章就介绍到这了,更多相关SpringBoot Shiro框架内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java安全框架——Shiro的使用详解(附springboot整合Shiro的demo)

    Shiro简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理 三个核心组件:Subject, SecurityManager 和 Realms Subject代表了当前用户的安全操作 SecurityManager管理所有用户的安全操作,是Shiro框架的核心,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务. Realm充当了Shiro与应用安全数据间的"桥梁"或者"连接器&q

  • 详解Java springboot 整合Shiro框架

    目录 Shiro介绍 Springboot整合Shiro Shiro整合Thymeleaf 总结 Shiro介绍 Shiro是一款安全框架,主要的三个类Subject.SecurityManager.Realm Subject:表示当前用户 SecurityManager:安全管理器,即所有与安全有关的操作都会与SecurityManager交互:且其管理着所有Subject:可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC中DispatcherSe

  • SpringBoot整合Shiro框架,实现用户权限管理

    一.Shiro简介 核心角色 1)Subject:认证主体 代表当前系统的使用者,就是用户,在Shiro的认证中,认证主体通常就是userName和passWord,或者其他用户相关的唯一标识. 2)SecurityManager:安全管理器 Shiro架构中最核心的组件,通过它可以协调其他组件完成用户认证和授权.实际上,SecurityManager就是Shiro框架的控制器. 3)Realm:域对象 定义了访问数据的方式,用来连接不同的数据源,如:关系数据库,配置文件等等. 核心理念 Shi

  • SpringBoot配置shiro安全框架的实现

    首先引入pom <!--SpringBoot 2.1.0--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> </parent> <!--shiro--> &l

  • SpringBoot2.0整合Shiro框架实现用户权限管理的示例

    GitHub源码地址:知了一笑 https://github.com/cicadasmile/middle-ware-parent 一.Shiro简介 1.基础概念 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.作为一款安全框架Shiro的设计相当巧妙.Shiro的应用不依赖任何容器,它不仅可以在JavaEE下使用,还可以应用在JavaSE环境中. 2.核心角色 1)Subject:认证主体 代表当前系统的使用者,就是用户,在Shiro的认证中,

  • springboot2.x整合shiro权限框架的使用

    序 在实际项目中,经常需要用到角色权限区分,以此来为不同的角色赋予不同的权利,分配不同的任务.比如,普通用户只能浏览:会员可以浏览和评论:超级会员可以浏览.评论和看视频课等:实际应用场景很多.毫不夸张的说,几乎每个完整的项目都会设计到权限管理. 在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是由于 Spring Security 过于庞大和复杂,只要能满足业务需要,大多数公司还是会选择 Apache Shiro 来使用. 一般来说,Spri

  • SpringBoot浅析安全管理之Shiro框架

    目录 Shiro 简介 整合 Shiro 1. 创建项目 2. Shiro基本配置 3. 测试 Shiro 简介 Apache Shiro 是一个开源的轻量级的 Java 安全框架,它提供身份验证.授权.密码管理以及会话管理等功能.相对于 Spring Security ,Shiro 框架更加直观.易用,同时也能提供健壮的安全性. 在传统的 SSM 框架中,手动整合 Shiro 的配置步骤还是比较多的,针对 Spring Boot ,Shiro 官方提供了 shiro-spring-boot-w

  • SpringBoot浅析安全管理之OAuth2框架

    目录 OAuth2简介 OAuth2角色 OAuth2授权流程 授权模式 实践 1. 创建项目添加依赖 2. 配置授权服务器 3. 配置资源服务器 4. 配置 Security 5. 验证测试 OAuth2简介 OAuth 是一个开放标准,该标准允许用户让第三方应用访问该用户在某一网站上存储的私密资源(如头像.照片.视频等),而在这个过程中无须将用户名和密码提供给第三方应用. 实现这一功能是通过一个令牌(token),而不是用户名和密码来访问他们存放在特定服务提供者的数据.每一个令牌授权一个特定

  • SpringBoot浅析安全管理之Spring Security配置

    目录 Spring Security 的基本配置 基本用法 1. 创建项目添加依赖 2. 添加 hello 接口 3. 启动项目测试 配置用户名和密码 基于内存的认证 HttpSecurity 登录表单详细配置 注销登录配置 多个 HttpSecurity 密码加密 1. 为什么要加密 2. 加密方案 3. 实践 方法安全 在 Java 开发领域常见的安全框架有 Shiro 和 Spring Security.Shiro 是一个轻量级的安全管理框架,提供了认证.授权.会话管理.密码管理.缓存管理

  • SpringBoot浅析安全管理之高级配置

    目录 角色继承 动态权限配置 1. 数据库设计 2. 自定义FilterInvocationSecurityMetadataSource 3. 自定义 AccessDecisionManager 4. 配置 角色继承 SpringBoot浅析安全管理之基于数据库认证中定义了三种角色,但是这三种角色之间不具备任何关系,一般来说角色之间是有关系的,例如 ROLE_admin 一般既具有 admin 权限,又具有 user 权限.那么如何配置这种角色继承关系呢?只需要开发者在 Spring Secur

  • SpringBoot浅析安全管理之基于数据库认证

    目录 1. 设计数据表 2. 创建项目 3. 配置数据库 4. 创建实体类 5. 创建UserService 6. 配置Spring Security 7.创建Controller 8. 测试 1. 设计数据表 用户表.角色表.用户角色关联表 建表语句 CREATE TABLE `role` ( `id` int(11) NOT NULL, `name` varchar(32) DEFAULT NULL, `nameZh` varchar(32) DEFAULT NULL, PRIMARY KE

  • Apache Shiro 框架简介

    一.什么是Shiro  Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户"登录": 授权 - 访问控制: 密码加密 - 保护或隐藏数据防止被偷窥: 会话管理 - 每用户相关的时间敏感的状态. 对于任何一个应用程序,Shiro都可以提供全面的安全管理服务.并且相对于其他安全框架,Shiro要简单的多. 二.Shiro的架构介绍  首先,来了解一下Shiro的三个核心组件:Subject, Se

  • springboot整合jquery和bootstrap框架过程图解

    这篇文章主要介绍了springboot整合jquery和bootstrap框架过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.4.1</version> </dependency>

随机推荐