SSM+Shiro搭建权限管理

来源:互联网 发布:安卓应用市场排名优化 编辑:程序博客网 时间:2024/05/16 23:44

一、shiro介绍

Shiro过滤器参数:
  1. anon:例子/admins/**=anon 没有参数,表示可以匿名使用。   
  2. authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数   
  3. roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。   
  4. perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。   
  5. rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。   
  6. port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。   
  7. authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证   
  8. ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https   
  9. user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查  

shiro的JSP标签使用

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

  1. <shiro:authenticated> 登录之后  
  2. <shiro:notAuthenticated> 不在登录状态时  
  3. <shiro:guest> 用户在没有RememberMe时  
  4. <shiro:user> 用户在RememberMe时  
  5. <shiro:hasAnyRoles name="abc,123" > 在有abc或者123角色时  
  6. <shiro:hasRole name="abc"> 拥有角色abc  
  7. <shiro:lacksRole name="abc"> 没有角色abc  
  8. <shiro:hasPermission name="abc"> 拥有权限abc  
  9. <shiro:lacksPermission name="abc"> 没有权限abc  
  10. <shiro:principal> 显示用户登录名  


二、表设计

实现用户->角色->权限 需要五张表

用户表(t_user)


角色表(t_role)


权限表(t_permission)



用户角色关联表(t_role_user)



角色权限关联表(t_permission_role)



三、实体和映射文件的建立

我们需要三个实体和一个映射文件UserMapper.xml

用户实体(要包含一个角色集合)

角色实体(要包含一个权限集合)

权限实体

看代码:

User.java

package com.lei.entity;import java.util.HashSet;import java.util.Set;public class User {private String id;private String username;private String password;//roleSet记得跟UserMapping里面表关联时字段名字相对应private Set<Role> roleSet = new HashSet<Role>();public String getId() {return id;}public void setId(String id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Set<Role> getRoleSet() {return roleSet;}public void setRoleSet(Set<Role> roleSet) {this.roleSet = roleSet;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((id == null) ? 0 : id.hashCode());result = prime * result + ((password == null) ? 0 : password.hashCode());result = prime * result + ((roleSet == null) ? 0 : roleSet.hashCode());result = prime * result + ((username == null) ? 0 : username.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;User other = (User) obj;if (id == null) {if (other.id != null)return false;} else if (!id.equals(other.id))return false;if (password == null) {if (other.password != null)return false;} else if (!password.equals(other.password))return false;if (roleSet == null) {if (other.roleSet != null)return false;} else if (!roleSet.equals(other.roleSet))return false;if (username == null) {if (other.username != null)return false;} else if (!username.equals(other.username))return false;return true;}  }
Role.java

package com.lei.entity;import java.util.HashSet;import java.util.Set;public class Role {private String id;private String name;//permissionSet记得跟UserMapping里面表关联时字段名字相对应private Set<Permission> permissionSet = new HashSet<>();public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Permission> getPermissionSet() {return permissionSet;}public void setPermissionSet(Set<Permission> permissionSet) {this.permissionSet = permissionSet;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((id == null) ? 0 : id.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());result = prime * result + ((permissionSet == null) ? 0 : permissionSet.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Role other = (Role) obj;if (id == null) {if (other.id != null)return false;} else if (!id.equals(other.id))return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;if (permissionSet == null) {if (other.permissionSet != null)return false;} else if (!permissionSet.equals(other.permissionSet))return false;return true;}}
Permission.java


package com.lei.entity;public class Permission {private String id;private String name;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((id == null) ? 0 : id.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Permission other = (Permission) obj;if (id == null) {if (other.id != null)return false;} else if (!id.equals(other.id))return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}}


UserMapper.xml  (重点)

<?xml version="1.0" encoding="UTF-8" ?>  <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >  <mapper namespace="com.lei.dao.UserDao">    <resultMap id="userMap" type="com.lei.entity.User">    <id property="id" column="user_id"/>    <result property="username" column="username"/>    <result property="password" column="password"/>    <!-- 进行 多表关联插叙,先关联user和role -->    <collection property="roleSet" column="role_id" ofType="com.lei.entity.Role">    <id property="id" column="role_id"/>    <result property="name" column="role_name"/>    <!-- 再在role中关联role和permission -->    <collection property="permissionSet" column="permission_id" ofType="com.lei.entity.Permission">    <id property="id" column="permission_id"/>    <result property="name" column="permission_name"/>    </collection>    </collection>    </resultMap>    <sql id="select-base">        SELECT           u.user_id,          u.username,          u.password,          r.role_id,          r.role_name,          p.permission_id,          p.permission_name        FROM          t_user as u,          t_role as r,          t_permission as p,          t_permission_role as pr,          t_role_user as ru        WHERE          u.user_id = ru.user_id    AND          r.role_id = ru.role_id        AND          p.permission_id = pr.permission_id        AND          r.role_id = pr.role_id      </sql>       <!--通过username返回user信息,里面包含有此user的全部角色实体 -->  <select id="findUserByUsername" parameterType="string" resultMap="userMap">         <include refid="select-base" />        AND          u.username = #{username}     </select>    </mapper>  



四、将SSM和Shiro整合

配置文件:

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>    <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:p="http://www.springframework.org/schema/p"      xmlns:aop="http://www.springframework.org/schema/aop"       xmlns:context="http://www.springframework.org/schema/context"      xmlns:jee="http://www.springframework.org/schema/jee"      xmlns:tx="http://www.springframework.org/schema/tx"      xsi:schemaLocation="            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd          http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">            <!-- 自动扫描 --><context:component-scan base-package="com.lei.service" /><!-- 配置数据源 --><bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/shiro"/><property name="username" value="root"/><property name="password" value="123456"/></bean><!-- 配置mybatis的sqlSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><!-- 自动扫描mappers.xml文件 --><property name="mapperLocations" value="classpath:mappers/*.xml"></property><!-- mybatis配置文件 --><property name="configLocation" value="classpath:mybatis-config.xml"></property></bean><!-- DAO接口所在包名,Spring会自动查找其下的类 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.lei.dao" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property></bean><!-- (事务管理)transaction manager, use JtaTransactionManager for global tx --><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!-- 自定义Realm --><bean id="myRealm" class="com.lei.shiro.UserRealm"/>  <!-- 安全管理器 --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">      <property name="realm" ref="myRealm"/>  </bean>  <!-- Shiro过滤器 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">      <!-- Shiro的核心安全接口,这个属性是必须的 -->      <property name="securityManager" ref="securityManager"/>    <!-- 身份认证失败,则跳转到登录页面的配置 -->      <property name="loginUrl" value="/index.jsp"/>    <!-- 权限认证失败,则跳转到指定页面 -->      <property name="unauthorizedUrl" value="/unauthorized.jsp"/>      <!-- Shiro连接约束配置,即过滤链的定义 -->      <property name="filterChainDefinitions">          <value>             /user/login.do=anon             /admin/*=roles["超级管理员"]/student/*=roles["学生"]/book/add=perms["book:create"]        </value>      </property></bean>  <!-- rememberMeManager管理器 -->    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">        <property name="cookie" ref="rememberMeCookie" />    </bean>    <!-- 记住我cookie -->    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">        <constructor-arg value="rememberMe" />        <!-- 记住我cookie生效时间30天 -->        <property name="maxAge" value="2592000" />    </bean><!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->  <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  <!-- 开启Shiro注解 --><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">      <property name="securityManager" ref="securityManager"/>      </bean>    <!-- 配置事务通知属性 -->      <tx:advice id="txAdvice" transaction-manager="transactionManager">          <!-- 定义事务传播属性 -->          <tx:attributes>              <tx:method name="insert*" propagation="REQUIRED" />              <tx:method name="update*" propagation="REQUIRED" />              <tx:method name="edit*" propagation="REQUIRED" />              <tx:method name="save*" propagation="REQUIRED" />              <tx:method name="add*" propagation="REQUIRED" />              <tx:method name="new*" propagation="REQUIRED" />              <tx:method name="set*" propagation="REQUIRED" />              <tx:method name="remove*" propagation="REQUIRED" />              <tx:method name="delete*" propagation="REQUIRED" />              <tx:method name="change*" propagation="REQUIRED" />              <tx:method name="check*" propagation="REQUIRED" />              <tx:method name="get*" propagation="REQUIRED" read-only="true" />              <tx:method name="find*" propagation="REQUIRED" read-only="true" />              <tx:method name="load*" propagation="REQUIRED" read-only="true" />              <tx:method name="*" propagation="REQUIRED" read-only="true" />          </tx:attributes>      </tx:advice>        <!-- 配置事务切面 -->      <aop:config>          <aop:pointcut id="serviceOperation"              expression="execution(* com.lei.service.*.*(..))" />          <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />      </aop:config>  </beans>

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>    <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:p="http://www.springframework.org/schema/p"      xmlns:aop="http://www.springframework.org/schema/aop"       xmlns:context="http://www.springframework.org/schema/context"      xmlns:jee="http://www.springframework.org/schema/jee"      xmlns:tx="http://www.springframework.org/schema/tx"      xsi:schemaLocation="            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd          http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">    <!-- 使用注解的包,包括子集 --><context:component-scan base-package="com.lei.controller" /><!-- 视图解析器 --><bean id="viewResolver"class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/" /><property name="suffix" value=".jsp"></property></bean></beans>  

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 别名 --><typeAliases><package name="com.lei.entity"/></typeAliases></configuration>

web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  <display-name>Shiro</display-name>  <welcome-file-list>    <welcome-file>index.jsp</welcome-file>  </welcome-file-list>    <!-- shiro过滤器定义 --><filter>      <filter-name>shiroFilter</filter-name>      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>      <init-param>      <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->      <param-name>targetFilterLifecycle</param-name>      <param-value>true</param-value>      </init-param>  </filter>  <filter-mapping>          <filter-name>shiroFilter</filter-name>          <url-pattern>/*</url-pattern>  </filter-mapping>    <!-- Spring配置文件 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><!-- 编码过滤器 --><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- Spring监听器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 添加对springmvc的支持 --><servlet><servlet-name>springMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><!-- 拦截URL --><servlet-mapping><servlet-name>springMVC</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping></web-app>


log4j.properties

log4j.rootLogger=DEBUG, Console    #Console  log4j.appender.Console=org.apache.log4j.ConsoleAppender  log4j.appender.Console.layout=org.apache.log4j.PatternLayout  log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n    log4j.logger.java.sql.ResultSet=INFO  log4j.logger.org.apache=INFO  log4j.logger.java.sql.Connection=DEBUG  log4j.logger.java.sql.Statement=DEBUG  log4j.logger.java.sql.PreparedStatement=DEBUG  

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>shiro</groupId><artifactId>shiro</artifactId><version>0.0.1-SNAPSHOT</version><name>shiro Maven Webapp</name><packaging>war</packaging><!-- 版本设置 --><properties><mybatis.version>3.4.5</mybatis.version><spring.version>5.0.0.RELEASE</spring.version><junit.version>4.10</junit.version><spring-mybatis.version>1.3.1</spring-mybatis.version><mysql-connector.version>5.1.44</mysql-connector.version><druid.version>1.1.3</druid.version><shiro.version>1.4.0</shiro.version></properties><dependencies><!-- 添加mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><!-- 添加mybatis和Spring的整合 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${spring-mybatis.version}</version></dependency><!-- 添加Spring支持 --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><!-- mysql链接驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql-connector.version}</version></dependency><!-- druid数据源 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency><!-- 添加对shiro的支持 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>${shiro.version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro.version}</version></dependency><!-- slf4j支持 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.25</version><scope>test</scope></dependency><!-- junit单元测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency><!-- 文件上传工具类 --><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version></dependency><!-- 添加对日志的支持 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!-- fastJson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.38</version></dependency><!-- servlet-api提供HttpServletRequest --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.0</version><scope>provided</scope></dependency></dependencies><build><finalName>shiro</finalName></build></project>


项目完整打包下载:http://download.csdn.net/download/junmoxi/10136548


原创粉丝点击