一、前言
在Web应用中,身份认证和权限控制是非常重要的组成部分,Shiro作为一个灵活的、功能强大的Java安全框架,在开发过程中可以方便地实现各种安全需求,因此被广泛应用于各种Java项目中。而Spring则作为一个非常流行的开发框架,与Shiro的整合可以解决现代Web应用中的常见安全问题。
本文将详细讲解如何在Spring项目中集成Shiro,并使用EL表达式扩展Shiro的功能,希望对想要学习Shiro或者正在开发使用Shiro的读者有所帮助。
二、整合Shiro
- 添加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>
- 配置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。
- 配置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表示退出登录的操作,/**表示需要认证后才能访问的页面。
- 配置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表达式
- 配置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方法。
- 扩展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:使用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则用于判断用户是否不拥有指定的角色。
- 示例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技术站