Spring 整合Shiro 并扩展使用EL表达式的实例详解

一、前言

在Web应用中,身份认证和权限控制是非常重要的组成部分,Shiro作为一个灵活的、功能强大的Java安全框架,在开发过程中可以方便地实现各种安全需求,因此被广泛应用于各种Java项目中。而Spring则作为一个非常流行的开发框架,与Shiro的整合可以解决现代Web应用中的常见安全问题。

本文将详细讲解如何在Spring项目中集成Shiro,并使用EL表达式扩展Shiro的功能,希望对想要学习Shiro或者正在开发使用Shiro的读者有所帮助。

二、整合Shiro

  1. 添加Shiro的Maven依赖

在pom.xml文件中添加以下依赖:

<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>1.7.1</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-web</artifactId>
  <version>1.7.1</version>
</dependency>
  1. 配置Shiro的SecurityManager

在Spring的配置文件(如applicationContext.xml)中添加以下配置:

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
  <!-- 设置自定义Realm,用于认证和授权 -->
  <property name="realm" ref="myRealm"/>
</bean>

其中myRealm是自定义的Realm类,需要继承org.apache.shiro.realm.Realm类,并实现其中的抽象方法doGetAuthenticationInfo和doGetAuthorizationInfo。

  1. 配置Shiro的FilterChain

在Spring的配置文件中添加以下配置:

<bean id="shiroFilter" class="org.apache.shiro.web.servlet.ShiroFilter">
  <property name="securityManager" ref="securityManager"/>
  <!-- 配置URL的访问规则和需要的权限 -->
  <property name="filterChainDefinitions">
    <value>
      /login.jsp = anon
      /logout = logout
      /** = authc
    </value>
  </property>
</bean>

其中,/login.jsp表示匿名访问的页面,/logout表示退出登录的操作,/**表示需要认证后才能访问的页面。

  1. 配置Shiro的DelegatingFilterProxy

在web.xml中添加以下配置:

<!-- Shiro Filter -->
<filter>
  <filter-name>shiroFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>shiroFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

至此,我们已经完成了Shiro与Spring的整合。在Shiro的基础上,我们可以继续扩展其功能。

三、扩展使用EL表达式

  1. 配置Spring的EL表达式支持

在Spring的配置文件中添加以下配置:

<bean id="defaultWebSecurityManager" parent="securityManager">
  <property name="subjectFactory">
    <bean class="org.apache.shiro.web.mgt.DefaultWebSubjectFactory">
      <!-- 使用Spring EL表达式来启用Session管理 -->
      <property name="sessionCreationEnabled" value="#{sessionManager.sessionValidationScheduler != null}"/>
    </bean>
  </property>
</bean>

其中,sessionManager是自定义的Session管理类,需要继承org.apache.shiro.web.session.mgt.DefaultWebSessionManager,并重写其getSessionId方法。

  1. 扩展Shiro的EL表达式

在Spring的配置文件中添加以下配置:

<bean id="shiroExpressionResolver" class="org.apache.shiro.spring.security.interceptor.SpringSecurityExpressionResolver"/>
<bean id="defaultFilterChainManager" class="org.apache.shiro.web.filter.mgt.DefaultFilterChainManager">
  <!-- 配置URL的访问规则和需要的权限,使用Spring EL表达式 -->
  <property name="filterChainDefinitionBuilder" ref="filterChainDefinitionBuilder"/>
</bean>
<bean id="filterChainDefinitionBuilder" class="org.apache.shiro.spring.web.config.DefaultFilterChainDefinitionBuilder">
  <property name="filterChainManager" ref="defaultFilterChainManager"/>
  <property name="resourcePathPrefix" value="/"/>
  <property name="definitions">
    <props>
      <prop key="/login.jsp">anon</prop>
      <prop key="/logout">logout</prop>
      <prop key="/**">authc && hasAnyRole('admin', 'user')</prop>
    </props>
  </property>
  <!-- 使用Spring EL表达式 -->
  <property name="expressionHandler">
    <bean class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
      <property name="permissionEvaluator">
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
          <property name="securityManager" ref="defaultWebSecurityManager"/>
          <property name="resourcePermissionResolver">
            <bean class="org.apache.shiro.spring.security.interceptor.SpringSecurityResourcePermissionResolver"/>
          </property>
        </bean>
      </property>
    </bean>
  </property>
</bean>

其中,我们配置了支持EL表达式的表达式解析器shiroExpressionResolver,并使用它来扩展filterChainDefinitionBuilder。在filterChainDefinitionBuilder中,我们使用了EL表达式来配置URL的访问规则和需要的权限,并使用Spring EL表达式的DefaultMethodSecurityExpressionHandler来解析EL表达式。

  1. 示例1:使用EL表达式进行用户权限判断

在jsp页面中,我们可以使用如下代码:

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>首页</title>
</head>
<body>
  <h1>欢迎访问首页!</h1>
  <shiro:hasRole name="admin">
    <p>您是管理员,可以查看所有用户信息!</p>
  </shiro:hasRole>
  <shiro:lacksRole name="admin">
    <p>您不是管理员,无法查看所有用户信息!</p>
  </shiro:lacksRole>
</body>
</html>

其中,shiro:hasRole用于判断用户是否拥有指定的角色,shiro:lacksRole则用于判断用户是否不拥有指定的角色。

  1. 示例2:使用EL表达式进行资源权限判断

在jsp页面中,我们可以使用如下代码:

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>用户信息</title>
</head>
<body>
  <h1>用户信息</h1>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>用户名</th>
        <th>年龄</th>
        <th>性别</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <shiro:forEach var="user" items="${users}">
        <tr>
          <td>${user.id}</td>
          <td>${user.username}</td>
          <td>${user.age}</td>
          <td>${user.gender}</td>
          <td>
            <shiro:hasPermission name="user:update:${user.id}">
              <a href="/user/${user.id}">编辑</a>
            </shiro:hasPermission>
            <shiro:lacksPermission name="user:update:${user.id}">
              无权限
            </shiro:lacksPermission>
          </td>
        </tr>
      </shiro:forEach>
    </tbody>
  </table>
</body>
</html>

其中,shiro:hasPermission用于判断用户是否拥有指定的资源权限,shiro:lacksPermission则用于判断用户是否不拥有指定的资源权限。

至此,我们已经完成了Shiro的整合和扩展使用EL表达式的示例。希望对读者有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring 整合Shiro 并扩展使用EL表达式的实例详解 - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • Java数据库操作库DButils类的使用方法与实例详解

    Java数据库操作库DButils类的使用方法与实例详解 一、概述 DButils是一款基于Java语言开发的数据库操作库,具有使用简单、功能丰富、高效性等特点。在Java开发中,使用DButils可以让我们更加方便地进行数据库操作,节省我们大量的时间和精力。DButils提供了一组用于执行SQL语句和映射结果集的API,除此之外,还提供了连接池和事务管理等…

    Java 2023年5月19日
    00
  • IDEA搭建SpringBoot离线工程的方法

    IDEA搭建Spring Boot离线工程的方法 在本文中,我们将详细介绍如何使用 IntelliJ IDEA 搭建 Spring Boot 离线工程。我们将介绍离线工程的概念、搭建步骤和提供两个示例。 离线工程概念 离线工程是指在没有网络连接的情况下,使用本地的依赖库和插件来构建和运行 Spring Boot 应用程序。离线工程可以帮助我们在没有网络连接的…

    Java 2023年5月15日
    00
  • Java组件javabean用户登录实例详解

    Java组件javabean用户登录实例详解 什么是JavaBean? JavaBean 是Java语言编写的可重用组件,具有如下特征: 公共的无参构造方法 成员变量为私有的,公共的Getter和Setter方法 可序列化 用户登录实例 本文将介绍如何使用JavaBean实现用户登录功能。 编写JavaBean 首先,我们要编写一个JavaBean,该Jav…

    Java 2023年6月15日
    00
  • 解决netty中spring对象注入失败的问题

    解决Netty中Spring对象注入失败的问题,一般存在两个方面的问题: 在Netty的handler中无法注入Spring的bean; 在Netty的线程中使用Spring的事务管理器会出现异常报错。 为了解决这两个问题,我们需要按照以下步骤进行: 步骤一:引入spring-boot-starter-netty 在Spring Boot项目中,通过添加sp…

    Java 2023年6月16日
    00
  • java实现简单的计算器类实例

    下面是Java实现简单的计算器类实例的攻略: 步骤1:创建Calculator类 首先我们需要创建一个Calculator类,这个类将会有4个方法add, subtract, multiply和 divide,这些方法将用于执行加法、减法、乘法和除法操作。 public class Calculator { // 加法 public double add(d…

    Java 2023年6月15日
    00
  • java线程池参数位置导致的夺命故障宿主机打不开

    线程池是一种常见的并发处理机制,它可以有效地管理线程的生命周期,避免频繁创建和销毁线程而导致系统开销过大的问题。不过,在进行线程池的使用时,需要设置相应的参数,否则可能会导致不可预料的问题。 下面是针对“java线程池参数位置导致的夺命故障宿主机打不开”的攻略,具体内容如下: 1. 背景介绍 在使用线程池时,常见的参数包括线程池大小、任务队列大小、线程空闲时…

    Java 2023年5月27日
    00
  • java中如何获取时间戳的方法实例

    获取时间戳可以使用Java中的两种方式:System.currentTimeMillis()和Instant.now().toEpochMilli()。 System.currentTimeMillis()方法实例 System.currentTimeMillis()方法返回当前时间戳(以毫秒为单位)。 示例代码: long timestamp = Syst…

    Java 2023年5月20日
    00
  • Sprint Boot @ConditionalOnBean使用方法详解

    @ConditionalOnBean是Spring Boot中的一个注解,它用于根据Spring容器中是否存在指定的Bean来决定是否启用或禁用某个组件。在使用Spring Boot开发应用程序时,@ConditionalOnBean是非常有用的。本文将详细介绍@ConditionalOnBean的作用和使用方法,并提供两个示例说明。 @Conditiona…

    Java 2023年5月5日
    00
合作推广
合作推广
分享本页
返回顶部