Shiro集成SSM基于URL权限管理(一)

学习了shiro之后,我们就可以说尝试把shiro加入ssm中,并做一套基于URL的权限管理。

其他的准备工作就不多说了,直接动手操作,看到效果再去理解。

表结构

执行如下,数据库名字可以自行修改,不过要和自己手动创建的数据库名字以及之后代码中的数据库名字保持一致。

 1 DROP DATABASE IF EXISTS shiro;
 2 CREATE DATABASE shiro DEFAULT CHARACTER SET utf8;
 3 USE shiro;
 4    
 5 drop table if exists user;
 6 drop table if exists role;
 7 drop table if exists permission;
 8 drop table if exists user_role;
 9 drop table if exists role_permission;
10    
11 create table user (
12   id bigint auto_increment,
13   name varchar(100),
14   password varchar(100),
15   salt varchar(100),
16   constraint pk_users primary key(id)
17 ) charset=utf8 ENGINE=InnoDB;
18    
19 create table role (
20   id bigint auto_increment,
21   name varchar(100),
22   desc_ varchar(100),
23   constraint pk_roles primary key(id)
24 ) charset=utf8 ENGINE=InnoDB;
25    
26 create table permission (
27   id bigint auto_increment,
28   name varchar(100),
29   desc_ varchar(100),
30   url varchar(100), 
31   constraint pk_permissions primary key(id)
32 ) charset=utf8 ENGINE=InnoDB;
33    
34 create table user_role (
35   id bigint auto_increment,
36   uid bigint,
37   rid bigint,
38   constraint pk_users_roles primary key(id)
39 ) charset=utf8 ENGINE=InnoDB;
40    
41 create table role_permission (
42   id bigint auto_increment,
43   rid bigint,
44   pid bigint,
45   constraint pk_roles_permissions primary key(id)
46 ) charset=utf8 ENGINE=InnoDB;
View Code

表数据

 1 INSERT INTO `permission` VALUES (1,'addProduct','增加产品','/addProduct');
 2 INSERT INTO `permission` VALUES (2,'deleteProduct','删除产品','/deleteProduct');
 3 INSERT INTO `permission` VALUES (3,'editeProduct','编辑产品','/editeProduct');
 4 INSERT INTO `permission` VALUES (4,'updateProduct','修改产品','/updateProduct');
 5 INSERT INTO `permission` VALUES (5,'listProduct','查看产品','/listProduct');
 6 INSERT INTO `permission` VALUES (6,'addOrder','增加订单','/addOrder');
 7 INSERT INTO `permission` VALUES (7,'deleteOrder','删除订单','/deleteOrder');
 8 INSERT INTO `permission` VALUES (8,'editeOrder','编辑订单','/editeOrder');
 9 INSERT INTO `permission` VALUES (9,'updateOrder','修改订单','/updateOrder');
10 INSERT INTO `permission` VALUES (10,'listOrder','查看订单','/listOrder');
11 INSERT INTO `role` VALUES (1,'admin','超级管理员');
12 INSERT INTO `role` VALUES (2,'productManager','产品管理员');
13 INSERT INTO `role` VALUES (3,'orderManager','订单管理员');
14 INSERT INTO `role_permission` VALUES (1,1,1);
15 INSERT INTO `role_permission` VALUES (2,1,2);
16 INSERT INTO `role_permission` VALUES (3,1,3);
17 INSERT INTO `role_permission` VALUES (4,1,4);
18 INSERT INTO `role_permission` VALUES (5,1,5);
19 INSERT INTO `role_permission` VALUES (6,1,6);
20 INSERT INTO `role_permission` VALUES (7,1,7);
21 INSERT INTO `role_permission` VALUES (8,1,8);
22 INSERT INTO `role_permission` VALUES (9,1,9);
23 INSERT INTO `role_permission` VALUES (10,1,10);
24 INSERT INTO `role_permission` VALUES (11,2,1);
25 INSERT INTO `role_permission` VALUES (12,2,2);
26 INSERT INTO `role_permission` VALUES (13,2,3);
27 INSERT INTO `role_permission` VALUES (14,2,4);
28 INSERT INTO `role_permission` VALUES (15,2,5);
29 INSERT INTO `role_permission` VALUES (50,3,10);
30 INSERT INTO `role_permission` VALUES (51,3,9);
31 INSERT INTO `role_permission` VALUES (52,3,8);
32 INSERT INTO `role_permission` VALUES (53,3,7);
33 INSERT INTO `role_permission` VALUES (54,3,6);
34 INSERT INTO `role_permission` VALUES (55,3,1);
35 INSERT INTO `role_permission` VALUES (56,5,11);
36 INSERT INTO `user` VALUES (1,'zhang3','a7d59dfc5332749cb801f86a24f5f590','e5ykFiNwShfCXvBRPr3wXg==');
37 INSERT INTO `user` VALUES (2,'li4','43e28304197b9216e45ab1ce8dac831b','jPz19y7arvYIGhuUjsb6sQ==');
38 INSERT INTO `user_role` VALUES (43,2,2);
39 INSERT INTO `user_role` VALUES (45,1,1);
View Code

 和我们正常创建ssm项目,一样。

web.xml

web.xml做了如下几件事情

1. 指定spring的配置文件有两个

applicationContext.xml: 用于链接数据库的

applicationContext-shiro.xml: 用于配置shiro的。

2. 指定springmvc的配置文件

springMVC.xml

3. 使用shiro过滤器

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

代码如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3          xmlns="http://java.sun.com/xml/ns/javaee"
 4          xmlns:web="http://java.sun.com/xml/ns/javaee"
 5          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
 6      
 7     <!-- 中文过滤器 -->
 8     <filter>
 9         <filter-name>CharacterEncodingFilter</filter-name>
10         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
11         <init-param>
12             <param-name>encoding</param-name>
13             <param-value>utf-8</param-value>
14         </init-param>
15     </filter>
16     <filter-mapping>
17         <filter-name>CharacterEncodingFilter</filter-name>
18         <url-pattern>/*</url-pattern>
19     </filter-mapping>
20          
21     <!-- spring的配置文件-->
22     <context-param>
23         <param-name>contextConfigLocation</param-name>
24         <param-value>
25             classpath:applicationContext.xml,
26             classpath:applicationContext-shiro.xml
27         </param-value>
28     </context-param>
29     <listener>
30         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
31     </listener>
32      
33     <!-- spring mvc核心:分发servlet -->
34     <servlet>
35         <servlet-name>mvc-dispatcher</servlet-name>
36         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
37         <!-- spring mvc的配置文件 -->
38         <init-param>
39             <param-name>contextConfigLocation</param-name>
40             <param-value>classpath:springMVC.xml</param-value>
41         </init-param>
42         <load-on-startup>1</load-on-startup>
43     </servlet>
44     <servlet-mapping>
45         <servlet-name>mvc-dispatcher</servlet-name>
46         <url-pattern>/</url-pattern>
47     </servlet-mapping>
48      
49     <!-- Shiro配置 -->
50     <filter>
51         <filter-name>shiroFilter</filter-name>
52         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
53         <init-param>
54             <param-name>targetFilterLifecycle</param-name>
55             <param-value>true</param-value>
56         </init-param>
57     </filter>
58     <filter-mapping>
59         <filter-name>shiroFilter</filter-name>
60         <url-pattern>/*</url-pattern>
61     </filter-mapping>
62      
63 </web-app>
View Code

applicationContext.xml

1.配置数据库的相关信息这些配置根据自己的需要自行修改
2. 扫描mybatis的mapper之类的

代码如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xmlns:mvc="http://www.springframework.org/schema/mvc"
 7     xsi:schemaLocation="
 8      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
 9      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
10      http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
11      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
12      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
13      http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
14     
15     
16     
17 
18    <context:annotation-config />
19     <context:component-scan base-package="com.how2java.service" />
20 
21     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
22       <property name="driverClassName">  
23           <value>com.mysql.jdbc.Driver</value>  
24       </property>  
25       <property name="url">  
26           <value>jdbc:mysql://localhost:3306/shiroweb?characterEncoding=UTF-8</value>  
27     
28       </property>  
29       <property name="username">  
30           <value>root</value>  
31       </property>  
32       <property name="password">  
33           <value>root</value>  
34       </property>      
35     </bean>
36     
37     
38     <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
39         <property name="typeAliasesPackage" value="com.how2java.pojo" />
40         <property name="dataSource" ref="dataSource"/>
41         <property name="mapperLocations" value="classpath:com/how2java/mapper/*.xml"/>
42     </bean>
43 
44     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
45         <property name="basePackage" value="com.how2java.mapper"/>
46     </bean>
47     
48 
49 
50 </beans>
View Code

applicationContext-shiro.xml

提供shiro的相关配置,简单的说,就是把我们之前做练习的shiro.ini里的内容搬到这个xml文件里面来了,只是写法不同

配合DatabaseRealm,做了 shiro教程中的shiro.ini 中做的事情
设置密码匹配器

<!-- 密码匹配器 -->

<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">

<property name="hashAlgorithmName" value="md5"/>

<property name="hashIterations" value="2"/>

<property name="storedCredentialsHexEncoded" value="true"/>

</bean>


DatabaseRealm使用这个密码匹配器

<bean id="databaseRealm" class="com.how2java.realm.DatabaseRealm">

<property name="credentialsMatcher" ref="credentialsMatcher"/>

</bean>

 代码如下:

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3     xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util"
  4     xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
  5     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
  6     xmlns:aop="http://www.springframework.org/schema/aop"
  7     xsi:schemaLocation="http://www.springframework.org/schema/beans
  8     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/tx
  9     http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context
 10     http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc
 11     http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop
 12     http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/util
 13     http://www.springframework.org/schema/util/spring-util.xsd">
 14      
 15     <!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->
 16     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
 17         <!-- 调用我们配置的权限管理器 -->
 18         <property name="securityManager" ref="securityManager" />
 19         <!-- 配置我们的登录请求地址 -->
 20         <property name="loginUrl" value="/login" />
 21         <!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 -->
 22         <property name="unauthorizedUrl" value="/unauthorized" />
 23         <!-- 退出 -->
 24         <property name="filters">
 25             <util:map>
 26                 <entry key="logout" value-ref="logoutFilter" />
 27             </util:map>
 28         </property>
 29         <!-- 权限配置 -->
 30         <property name="filterChainDefinitions">
 31             <value>
 32                 <!-- anon表示此地址不需要任何权限即可访问 -->
 33                 /login=anon
 34                 /index=anon
 35                 /static/**=anon
 36                 <!-- 只对业务功能进行权限管理,权限配置本身不需要没有做权限要求,这样做是为了不让初学者混淆 -->
 37                 /config/**=anon
 38                 /doLogout=logout
 39                 <!--所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/login -->
 40                 /** = authc
 41             </value>
 42         </property>
 43     </bean>
 44     <!-- 退出过滤器 -->
 45     <bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
 46         <property name="redirectUrl" value="/index" />
 47     </bean>
 48  
 49     <!-- 会话ID生成器 -->
 50     <bean id="sessionIdGenerator"
 51         class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" />
 52     <!-- 会话Cookie模板 关闭浏览器立即失效 -->
 53     <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
 54         <constructor-arg value="sid" />
 55         <property name="httpOnly" value="true" />
 56         <property name="maxAge" value="-1" />
 57     </bean>
 58     <!-- 会话DAO -->
 59     <bean id="sessionDAO"
 60         class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
 61         <property name="sessionIdGenerator" ref="sessionIdGenerator" />
 62     </bean>
 63     <!-- 会话验证调度器,每30分钟执行一次验证 ,设定会话超时及保存 -->
 64     <bean name="sessionValidationScheduler"
 65         class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler">
 66         <property name="interval" value="1800000" />
 67         <property name="sessionManager" ref="sessionManager" />
 68     </bean>
 69     <!-- 会话管理器 -->
 70     <bean id="sessionManager"
 71         class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
 72         <!-- 全局会话超时时间(单位毫秒),默认30分钟 -->
 73         <property name="globalSessionTimeout" value="1800000" />
 74         <property name="deleteInvalidSessions" value="true" />
 75         <property name="sessionValidationSchedulerEnabled" value="true" />
 76         <property name="sessionValidationScheduler" ref="sessionValidationScheduler" />
 77         <property name="sessionDAO" ref="sessionDAO" />
 78         <property name="sessionIdCookieEnabled" value="true" />
 79         <property name="sessionIdCookie" ref="sessionIdCookie" />
 80     </bean>
 81  
 82     <!-- 安全管理器 -->
 83     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
 84         <property name="realm" ref="databaseRealm" />
 85         <property name="sessionManager" ref="sessionManager" />
 86     </bean>
 87     <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
 88     <bean
 89         class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
 90         <property name="staticMethod"
 91             value="org.apache.shiro.SecurityUtils.setSecurityManager" />
 92         <property name="arguments" ref="securityManager" />
 93     </bean>
 94  
 95     <!-- 密码匹配器 -->
 96     <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
 97         <property name="hashAlgorithmName" value="md5"/>
 98         <property name="hashIterations" value="2"/>
 99         <property name="storedCredentialsHexEncoded" value="true"/>
100     </bean>
101  
102     <bean id="databaseRealm" class="com.how2java.realm.DatabaseRealm">
103         <property name="credentialsMatcher" ref="credentialsMatcher"/>
104     </bean>
105      
106     <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
107     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
108 </beans>
View Code

springMVC.xml

1.springmvc的基本配置
2. 增加了对shiro的支持
这样可以在控制器Controller上,使用像@RequireRole 这样的注解,来表示某个方法必须有相关的角色才能访问
3. 指定了异常处理类DefaultExceptionHandler,这样当访问没有权限的资源的时候,就会跳到统一的页面去显示错误信息

代码如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xmlns:mvc="http://www.springframework.org/schema/mvc"
 7     xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
 8         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
 9         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
10         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
11         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
12         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
13 
14 
15 
16     <context:annotation-config/>
17 
18     <context:component-scan base-package="com.how2java.controller">
19           <context:include-filter type="annotation" 
20           expression="org.springframework.stereotype.Controller"/>
21     </context:component-scan>
22 
23     <mvc:annotation-driven />
24     
25     <mvc:default-servlet-handler />
26 
27 
28     <bean
29         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
30         <property name="viewClass"
31             value="org.springframework.web.servlet.view.JstlView" />
32         <property name="prefix" value="/WEB-INF/jsp/" />
33         <property name="suffix" value=".jsp" />
34     </bean>
35     
36     <!--启用shiro注解 -->
37     <bean
38         class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
39         depends-on="lifecycleBeanPostProcessor">
40         <property name="proxyTargetClass" value="true" />
41     </bean>
42     <bean
43         class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
44         <property name="securityManager" ref="securityManager" />
45     </bean>
46     
47     <!-- 控制器异常处理 -->
48     <bean id="exceptionHandlerExceptionResolver" class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
49     </bean>
50     <bean class="com.how2java.exception.DefaultExceptionHandler"/>    
51 
52 </beans>
View Code

log4j.properties

代码如下:

1 # Global logging configuration
2 log4j.rootLogger=ERROR, stdout
3 # MyBatis logging configuration...
4 log4j.logger.com.how2java=TRACE
5 # Console output...
6 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
7 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
8 log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
View Code

PageController.java

因为使用 ssm,所以jsp通常都会放在WEB-INF/jsp 下面,而这个位置是无法通过浏览器直接访问的,所以就会专门做这么一个类,便于访问这些jsp。
比如要访问WEB-INF/jsp/index.jsp文件,那么就通过/index 这个路径来访问。
这个类还有两点需要注意:
1. /login 只支持get方式。 post方式是后续用来进行登录行为的,这里的get方式仅仅用于显示登录页面
2. 权限注解:
通过注解: @RequiresRoles("admin") 指明了 访问 deleteProduct 需要角色"admin" 
通过注解:@RequiresPermissions("deleteOrder") 指明了 访问 deleteOrder 需要权限"deleteOrder" 

我们在哪里需要使用权限,就在哪里加上对应注解,但是当我们的权限配置关系发生改变的时候,我们不得不修改代码,这在实际项目中是不可能的。为了解决这一问题我们引入了url配置权限。

代码如下:

 1 package com.how2java.controller;
 2 
 3 
 4 import org.apache.shiro.authz.annotation.RequiresPermissions;
 5 import org.apache.shiro.authz.annotation.RequiresRoles;
 6 import org.springframework.stereotype.Controller;
 7 import org.springframework.web.bind.annotation.RequestMapping;
 8 import org.springframework.web.bind.annotation.RequestMethod;
 9 
10 //专门用于显示页面的控制器
11 @Controller
12 @RequestMapping("")
13 public class PageController {
14     
15     @RequestMapping("index")
16     public String index(){
17         return "index";
18     }
19     
20     @RequiresPermissions("deleteOrder")
21     @RequestMapping("deleteOrder")
22     public String deleteOrder(){
23         return "deleteOrder";
24     }
25     @RequiresRoles("productManager")
26     @RequestMapping("deleteProduct")
27     public String deleteProduct(){
28         return "deleteProduct";
29     }
30     @RequestMapping("listProduct")
31     public String listProduct(){
32         return "listProduct";
33     }
34     
35     @RequestMapping(value="/login",method=RequestMethod.GET)  
36     public String login(){
37         return "login";
38     }
39     @RequestMapping("unauthorized")
40     public String noPerms(){
41         return "unauthorized";
42     }
View Code

View层的各个页面

直接贴出结构图和代码

index页面

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6 
 7 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 8 
 9 <link rel="stylesheet" type="text/css" href="static/css/style.css" />
10 
11 
12 </head>
13 <body>
14 
15 
16 
17 <div class="workingroom">
18     <div class="loginDiv">
19     
20     
21 
22     <c:if test="${empty subject.principal}">
23         <a href="login">登录</a><br>
24     </c:if>
25     <c:if test="${!empty subject.principal}">
26         <span class="desc">你好,${subject.principal},</span>
27         <a href="doLogout">退出</a><br>    
28     </c:if>
29         
30     <a href="listProduct">查看产品</a><span class="desc">(登录后才可以查看) </span><br>
31     <a href="deleteProduct">删除产品</a><span  class="desc">(要有产品管理员角色, zhang3没有,li4 有) </span><br>
32     <a href="deleteOrder">删除订单</a><span class="desc">(要有删除订单权限, zhang3有,li4没有) </span><br>
33 </div>
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 </body>
44 </html>
View Code

login.jsp登陆页面

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8" import="java.util.*"%>
 3  
 4 <!DOCTYPE html>
 5  
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <link rel="stylesheet" type="text/css" href="static/css/style.css" />
 8 
 9  
10 <div class="workingroom">
11 
12 <div class="errorInfo">${error}</div>
13     <form action="login" method="post">
14         账号: <input type="text" name="name"> <br>
15         密码: <input type="password" name="password"> <br>
16         <br>
17         <input type="submit" value="登录">
18         <br>
19         <br>
20     <div>
21         <span class="desc">账号:zhang3 密码:12345 角色:admin</span><br>
22         <span class="desc">账号:li4 密码:abcde 角色:productManager</span><br>
23     </div>
24         
25         
26     </form>
27 </div>
View Code

listProduct.jsp  需要登录才能访问的页面

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8" import="java.util.*"%>
 3  
 4 <!DOCTYPE html>
 5  
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <link rel="stylesheet" type="text/css" href="static/css/style.css" />
 8 
 9  
10 <div class="workingroom">
11 
12     listProduct.jsp ,能进来,就表示已经登录成功了
13     <br>
14     <a href="#" onClick="javascript:history.back()">返回</a>
15 </div>
View Code

deleteProduct.jsp 需要角色才能访问的页面

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8" import="java.util.*"%>
 3  
 4 <!DOCTYPE html>
 5  
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <link rel="stylesheet" type="text/css" href="static/css/style.css" />
 8 
 9  
10 <div class="workingroom">
11 
12     deleteProduct.jsp,能进来<br>就表示拥有 productManager 角色
13     <br>
14     <a href="#" onClick="javascript:history.back()">返回</a>
15 </div>
View Code

deleteOrder.jsp 需要权限deleteOrder 才能访问的页面

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8" import="java.util.*"%>
 3  
 4 <!DOCTYPE html>
 5  
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <link rel="stylesheet" type="text/css" href="static/css/style.css" />
 8 
 9 <div class="workingroom">
10 
11     deleteOrder.jsp ,能进来,就表示有deleteOrder权限
12     <br>
13     <a href="#" onClick="javascript:history.back()">返回</a>
14 </div>
View Code

unauthorized.jsp没有角色,没有权限都会跳转到这个页面来

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8" import="java.util.*"%>
 3  
 4 <!DOCTYPE html>
 5  
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <link rel="stylesheet" type="text/css" href="static/css/style.css" />
 8 
 9  
10 <div class="workingroom">
11 
12     
13     
14 
15     权限不足,具体原因:${ex.message}
16     <br>
17     <a href="#" onClick="javascript:history.back()">返回</a>
18 </div>
View Code

menu.jsp

1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2     pageEncoding="UTF-8"%>
3     <div class="menu">
4         <a href="listUser">用户管理</a>
5         <a href="listRole">角色管理</a>
6         <a href="listPermission">权限管理</a>
7     </div>
View Code

style.css

 1 span.desc{
 2     margin-left:20px;
 3     color:gray;
 4 }
 5 div.workingroom{
 6     margin:200px auto;
 7     width:600px;
 8     position:relative;
 9 }
10 div.workingroom a{
11 /*  display:inline-block; */
12 /*  margin-top:20px; */
13 }
14 div.loginDiv{
15     text-align: left;
16 }
17 div.errorInfo{
18     color:red;
19     font-size:0.65em;
20 }
21 div.workingroom td{
22     border:1px solid black;
23 }
24 div.workingroom table{
25     border-collapse:collapse;
26     width:100%;
27 }
28  
29 div.workingroom td{
30     border:1px solid black;
31 }
32  
33 div.workingroom div.menu{
34     position:absolute;
35     left:-160px;
36     top:-20px;
37 }
38 div.workingroom div.menu a{
39     display:block;
40     margin-top:20px;
41 }
42  
43 div.workingroom div.addOrEdit{
44     margin:20px;
45     text-align:center;
46 }
View Code

listUser.jsp

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6  
 7 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 8 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
 9  
10 <link rel="stylesheet" type="text/css" href="../static/css/style.css" />
11 </head>
12 <body>
13  
14 <div class="workingroom">
15     <%@include file="include/menu.jsp" %>
16     <table>
17         <tr>
18             <td>id</td>
19             <td>用户名称</td>
20             <td>用户密码</td>
21             <td>加密盐</td>
22             <td>角色</td>
23             <td>编辑</td>
24             <td>删除</td>
25         </tr>
26         <c:forEach items="${us}" var="u">
27             <tr>
28                 <td>${u.id}</td>
29                 <td>${u.name}</td>
30                 <td>${fn:substring(u.password, 0, 5)}...</td>
31                 <td>${fn:substring(u.salt, 0, 5)}...</td>
32                 <td>
33                      <c:forEach items="${user_roles[u]}" var="r">
34                         ${r.name} <br>
35                      </c:forEach>
36                 </td>
37                 <td><a href="editUser?id=${u.id}">编辑</a></td>
38                 <td><a href="deleteUser?id=${u.id}">删除</a></td>
39             </tr>
40         </c:forEach>
41     </table>
42      
43     <div class="addOrEdit" >
44         <form action="addUser" method="post">
45             用户名: <input type="text" name="name"> <br>
46             密码: <input type="password" name="password"> <br><br>
47             <input type="submit" value="增加">
48         </form>  
49     </div>
50 </div>
51 </body>
52 </html>
View Code

editUser.jsp

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6  
 7 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 8  
 9 <link rel="stylesheet" type="text/css" href="../static/css/style.css" />
10  
11 </head>
12 <body>
13  
14 <div class="workingroom">
15      
16     <%@include file="include/menu.jsp" %>
17  
18     <div class="addOrEdit" >
19         <form action="updateUser" method="post">
20             用户名: <input type="text" name="name" value="${user.name}"> <br><br>
21             密码: <input type="password" name="password" value="" placeholder="留空就表示不修改密码"> <br><br>
22             配置角色:<br>
23             <div style="text-align:left;width:300px;margin:0px auto;padding-left:50px">
24                 <c:forEach items="${rs}" var="r">
25                     <c:set var="hasRole" value="false" />
26                     <c:forEach items="${currentRoles}" var="currentRole">
27                         <c:if test="${r.id==currentRole.id}">
28                             <c:set var="hasRole" value="true" />
29                         </c:if>
30                     </c:forEach>
31                     <input type="checkbox"  ${hasRole?"checked='checked'":"" } name="roleIds" value="${r.id}"> ${r.name}<br>
32                 </c:forEach>
33             </div>
34              
35             <br>
36             <input type="hidden" name="id" value="${user.id}">
37             <input type="submit" value="修改">
38         </form>  
39     </div>
40 </div>
41 <script>
42 </script>
43 </body>
44 </html>
View Code

listRole.jsp

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6  
 7 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 8  
 9 <link rel="stylesheet" type="text/css" href="../static/css/style.css" />
10  
11 </head>
12 <body>
13  
14 <div class="workingroom">
15      
16     <%@include file="include/menu.jsp" %>
17      
18     <table>
19         <tr>
20             <td>id</td>
21             <td>角色名称</td>
22             <td>角色描述</td>
23             <td>权限</td>
24             <td>编辑</td>
25             <td>删除</td>
26         </tr>
27         <c:forEach items="${rs}" var="r">
28             <tr>
29                 <td>${r.id}</td>
30                 <td>${r.name}</td>
31                 <td>${r.desc_}</td>
32                 <td>
33                      <c:forEach items="${role_permissions[r]}" var="p">
34                         ${p.name} <br>
35                      </c:forEach>
36                 </td>
37                  
38                 <td><a href="editRole?id=${r.id}">编辑</a></td>
39                 <td><a href="deleteRole?id=${r.id}">删除</a></td>
40             </tr>
41         </c:forEach>
42     </table>
43      
44     <div class="addOrEdit" >
45         <form action="addRole" method="post">
46             角色名称: <input type="text" name="name"> <br>
47             角色描述: <input type="text" name="desc_"> <br><br>
48             <input type="submit" value="增加">
49         </form>  
50     </div>
51 </div>
52 </body>
53 </html>
View Code

editRole.jsp

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6  
 7 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 8  
 9 <link rel="stylesheet" type="text/css" href="../static/css/style.css" />
10  
11 </head>
12 <body>
13  
14 <div class="workingroom">
15      
16     <%@include file="include/menu.jsp" %>
17  
18     <div class="addOrEdit" >
19         <form action="updateRole" method="post">
20             角色名: <input type="text" name="name" value="${role.name}"> <br>
21             角色描述: <input type="text" name="desc_" value="${role.desc_}" > <br><br>
22             配置权限:<br>
23             <div style="text-align:left;width:300px;margin:0px auto;padding-left:50px">
24                 <c:forEach items="${ps}" var="p">
25                     <c:set var="hasPermission" value="false" />
26                     <c:forEach items="${currentPermissions}" var="currentPermission">
27                         <c:if test="${p.id==currentPermission.id}">
28                             <c:set var="hasPermission" value="true" />
29                         </c:if>
30                     </c:forEach>
31                     <input type="checkbox"  ${hasPermission?"checked='checked'":"" } name="permissionIds" value="${p.id}"> ${p.name}<br>
32                 </c:forEach>
33             </div>           
34              
35             <input type="hidden" name="id" value="${role.id}">
36             <input type="submit" value="修改">
37         </form>  
38     </div>
39 </div>
40 </body>
41 </html>
View Code

listPermission.jsp

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6  
 7 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 8  
 9 <link rel="stylesheet" type="text/css" href="../static/css/style.css" />
10  
11 </head>
12 <body>
13  
14 <div class="workingroom">
15      
16     <%@include file="include/menu.jsp" %>
17      
18     <table>
19         <tr>
20             <td>id</td>
21             <td>权限名称</td>
22             <td>权限描述</td>
23             <td>权限对应的路径</td>
24             <td>编辑</td>
25             <td>删除</td>
26         </tr>
27         <c:forEach items="${ps}" var="p">
28             <tr>
29                 <td>${p.id}</td>
30                 <td>${p.name}</td>
31                 <td>${p.desc_}</td>
32                 <td>${p.url}</td>
33                 <td><a href="editPermission?id=${p.id}">编辑</a></td>
34                 <td><a href="deletePermission?id=${p.id}">删除</a></td>
35             </tr>
36         </c:forEach>
37     </table>
38      
39     <div class="addOrEdit" >
40         <form action="addPermission" method="post">
41             权限名称: <input type="text" name="name"> <br>
42             权限描述: <input type="text" name="desc_"> <br>
43             权限对应的url: <input type="text" name="url"> <br><br>
44             <input type="submit" value="增加">
45         </form>  
46     </div>
47 </div>
48 </body>
49 </html>
View Code

editPermission.jsp

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <html>
 4 <head>
 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 6  
 7 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 8  
 9 <link rel="stylesheet" type="text/css" href="../static/css/style.css" />
10  
11 </head>
12 <body>
13  
14 <div class="workingroom">
15      
16     <%@include file="include/menu.jsp" %>
17  
18     <div class="addOrEdit" >
19         <form action="updatePermission" method="post">
20             权限名称: <input type="text" name="name" value="${permission.name}"> <br>
21             权限描述: <input type="text" name="desc_" value="${permission.desc_}"> <br>
22             权限对应的url: <input type="text" name="url"  value="${permission.url}"> <br><br>
23             <input type="hidden" name="id" value="${permission.id}">
24             <input type="submit" value="修改">
25         </form>  
26     </div>
27 </div>
28 </body>
29 </html>
View Code

OverIsMergeablePlugin.java

这个类的解释见,解决MybatisGenerator多次运行mapper生成重复内容

代码如下:

 1 package com.how2java.util;
 2   
 3 import org.mybatis.generator.api.GeneratedXmlFile;
 4  
 5 import org.mybatis.generator.api.IntrospectedTable;
 6 import org.mybatis.generator.api.PluginAdapter;
 7   
 8 import java.lang.reflect.Field;
 9 import java.util.List;
10   
11 public class OverIsMergeablePlugin extends PluginAdapter {
12     @Override
13     public boolean validate(List<String> warnings) {
14         return true;
15     }
16   
17     @Override
18     public boolean sqlMapGenerated(GeneratedXmlFile sqlMap, IntrospectedTable introspectedTable) {
19         try {
20             Field field = sqlMap.getClass().getDeclaredField("isMergeable");
21             field.setAccessible(true);
22             field.setBoolean(sqlMap, false);
23         } catch (Exception e) {
24             e.printStackTrace();
25         }
26         return true;
27     }
28 }
View Code

generatorConfig.xml

目录如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE generatorConfiguration
 3         PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
 4         "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
 5 <generatorConfiguration>
 6   
 7     <context id="DB2Tables"    targetRuntime="MyBatis3">
 8         <!--避免生成重复代码的插件-->
 9         <plugin type="com.how2java.util.OverIsMergeablePlugin" />
10   
11         <!--是否在代码中显示注释-->
12         <commentGenerator>
13             <property name="suppressDate" value="true" />
14             <property name="suppressAllComments" value="true" />
15         </commentGenerator>
16   
17         <!--数据库链接地址账号密码-->
18         <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/shiro" userId="root" password="admin">
19         </jdbcConnection>
20         <!--不知道做什么用的。。。反正贴上来了~-->
21         <javaTypeResolver>
22             <property name="forceBigDecimals" value="false"/>
23         </javaTypeResolver>
24         <!--生成pojo类存放位置-->
25         <javaModelGenerator targetPackage="com.how2java.pojo" targetProject="src">
26             <property name="enableSubPackages" value="true"/>
27             <property name="trimStrings" value="true"/>
28         </javaModelGenerator>
29         <!--生成xml映射文件存放位置-->
30         <sqlMapGenerator targetPackage="com.how2java.mapper" targetProject="src">
31             <property name="enableSubPackages" value="true"/>
32         </sqlMapGenerator>
33         <!--生成mapper类存放位置-->
34         <javaClientGenerator type="XMLMAPPER" targetPackage="com.how2java.mapper" targetProject="src">
35             <property name="enableSubPackages" value="true"/>
36         </javaClientGenerator>
37   
38         <!--生成对应表及类名-->
39         <table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
40             <property name="my.isgen.usekeys" value="true"/>
41             <property name="useActualColumnNames" value="true"/>
42             <generatedKey column="id" sqlStatement="JDBC"/>
43         </table>
44         <table tableName="role" domainObjectName="Role" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
45             <property name="my.isgen.usekeys" value="true"/>
46             <property name="useActualColumnNames" value="true"/>
47             <generatedKey column="id" sqlStatement="JDBC"/>
48         </table>
49         <table tableName="permission" domainObjectName="Permission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
50             <property name="my.isgen.usekeys" value="true"/>
51             <property name="useActualColumnNames" value="true"/>
52             <generatedKey column="id" sqlStatement="JDBC"/>
53         </table>
54         <table tableName="user_role" domainObjectName="UserRole" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
55             <property name="my.isgen.usekeys" value="true"/>
56             <property name="useActualColumnNames" value="true"/>
57             <generatedKey column="id" sqlStatement="JDBC"/>
58         </table>
59         <table tableName="role_permission" domainObjectName="RolePermission" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
60             <property name="my.isgen.usekeys" value="true"/>
61             <property name="useActualColumnNames" value="true"/>
62             <generatedKey column="id" sqlStatement="JDBC"/>
63         </table>
64  
65     </context>
66 </generatorConfiguration>
View Code

MybatisGenerator.java

代码如下:

 1 package com.how2java.util;
 2   
 3 import org.mybatis.generator.api.MyBatisGenerator;
 4 import org.mybatis.generator.config.Configuration;
 5 import org.mybatis.generator.config.xml.ConfigurationParser;
 6 import org.mybatis.generator.internal.DefaultShellCallback;
 7   
 8 import java.io.InputStream;
 9 import java.text.SimpleDateFormat;
10 import java.util.ArrayList;
11 import java.util.Date;
12 import java.util.List;
13   
14 public class MybatisGenerator {
15   
16     public static void main(String[] args) throws Exception {
17         String today = "2018-5-21";
18   
19         SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd");
20         Date now =sdf.parse(today);
21         Date d = new Date();
22   
23         if(d.getTime()>now.getTime()+1000*60*60*24){
24             System.err.println("——————未成成功运行——————");
25             System.err.println("——————未成成功运行——————");
26             System.err.println("本程序具有破坏作用,应该只运行一次,如果必须要再运行,需要修改today变量为今天,如:" + sdf.format(new Date()));
27             return;
28         }
29   
30         if(false)
31             return;
32         List<String> warnings = new ArrayList<String>();
33         boolean overwrite = true;
34         InputStream is= MybatisGenerator.class.getClassLoader().getResource("generatorConfig.xml").openStream();
35         ConfigurationParser cp = new ConfigurationParser(warnings);
36         Configuration config = cp.parseConfiguration(is);
37         is.close();
38         DefaultShellCallback callback = new DefaultShellCallback(overwrite);
39         MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
40         myBatisGenerator.generate(null);
41   
42         System.out.println("生成代码成功,只能执行一次,以后执行会覆盖掉mapper,pojo,xml 等文件上做的修改");
43   
44     }
45 }
View Code

运行 MybatisGenerator 以获取自动生成 Pojo、Example 和 Mapper

 

记得刷新一下项目。

Service层

 PermissionService

 1 package com.how2java.service;
 2  
 3 import java.util.List;
 4 import java.util.Set;
 5  
 6 import com.how2java.pojo.Permission;
 7 import com.how2java.pojo.Role;
 8  
 9 public interface PermissionService {
10     public Set<String> listPermissions(String userName);
11  
12     public List<Permission> list();
13     public void add(Permission permission);
14     public void delete(Long id);
15     public Permission get(Long id);
16     public void update(Permission permission);
17  
18     public List<Permission> list(Role role);
19      
20 }
View Code

RolePermissionService

1 package com.how2java.service;
2  
3 import com.how2java.pojo.Role;
4  
5 public interface RolePermissionService {
6     public void setPermissions(Role role, long[] permissionIds);
7     public void deleteByRole(long roleId);
8     public void deleteByPermission(long permissionId);
9 }
View Code

RoleService

 1 package com.how2java.service;
 2  
 3 import java.util.List;
 4 import java.util.Set;
 5  
 6 import com.how2java.pojo.Role;
 7 import com.how2java.pojo.User;
 8  
 9 public interface RoleService {
10     public Set<String> listRoleNames(String userName);
11     public List<Role> listRoles(String userName);
12     public List<Role> listRoles(User user);
13  
14     public List<Role> list();
15     public void add(Role role);
16     public void delete(Long id);
17     public Role get(Long id);
18     public void update(Role role);
19      
20 }
View Code

UserRoleService

 1 package com.how2java.service;
 2  
 3 import com.how2java.pojo.User;
 4  
 5 public interface UserRoleService {
 6  
 7     public void setRoles(User user, long[] roleIds);
 8     public void deleteByUser(long userId);
 9     public void deleteByRole(long roleId);
10      
11 }
View Code

UserService

package com.how2java.service;
 
import java.util.List;
import com.how2java.pojo.User;
public interface UserService {
    public String getPassword(String name);
    public User getByName(String name);
     
    public List<User> list();
    public void add(User user);
    public void delete(Long id);
    public User get(Long id);
    public void update(User user);
}
View Code

Service实现层

PermissionServiceImpl

 1 package com.how2java.service.impl;
 2  
 3 import java.util.ArrayList;
 4 import java.util.HashSet;
 5 import java.util.List;
 6 import java.util.Set;
 7  
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.stereotype.Service;
10  
11 import com.how2java.mapper.PermissionMapper;
12 import com.how2java.mapper.RolePermissionMapper;
13 import com.how2java.pojo.Permission;
14 import com.how2java.pojo.PermissionExample;
15 import com.how2java.pojo.Role;
16 import com.how2java.pojo.RolePermission;
17 import com.how2java.pojo.RolePermissionExample;
18 import com.how2java.service.PermissionService;
19 import com.how2java.service.RoleService;
20 import com.how2java.service.UserService;
21  
22 @Service
23 public class PermissionServiceImpl  implements PermissionService{
24  
25     @Autowired PermissionMapper permissionMapper;
26     @Autowired UserService userService;
27     @Autowired RoleService roleService;
28     @Autowired RolePermissionMapper rolePermissionMapper;
29  
30     @Override
31     public Set<String> listPermissions(String userName) {
32         Set<String> result = new HashSet<>();
33         List<Role> roles = roleService.listRoles(userName);
34          
35         List<RolePermission> rolePermissions = new ArrayList<>();
36          
37         for (Role role : roles) {
38             RolePermissionExample example = new RolePermissionExample();
39             example.createCriteria().andRidEqualTo(role.getId());
40             List<RolePermission> rps= rolePermissionMapper.selectByExample(example);
41             rolePermissions.addAll(rps);
42         }
43          
44         for (RolePermission rolePermission : rolePermissions) {
45             Permission p = permissionMapper.selectByPrimaryKey(rolePermission.getPid());
46             result.add(p.getName());
47         }
48          
49         return result;
50     }
51    @Override
52     public void add(Permission u) {
53         permissionMapper.insert(u);
54     }
55   
56     @Override
57     public void delete(Long id) {
58         permissionMapper.deleteByPrimaryKey(id);
59     }
60   
61     @Override
62     public void update(Permission u) {
63         permissionMapper.updateByPrimaryKeySelective(u);
64     }
65   
66     @Override
67     public Permission get(Long id) {
68         return permissionMapper.selectByPrimaryKey(id);
69     }
70   
71     @Override
72     public List<Permission> list(){
73         PermissionExample example =new PermissionExample();
74         example.setOrderByClause("id desc");
75         return permissionMapper.selectByExample(example);
76   
77     }
78     @Override
79     public List<Permission> list(Role role) {
80         List<Permission> result = new ArrayList<>();
81         RolePermissionExample example = new RolePermissionExample();
82         example.createCriteria().andRidEqualTo(role.getId());
83         List<RolePermission> rps = rolePermissionMapper.selectByExample(example);
84         for (RolePermission rolePermission : rps) {
85             result.add(permissionMapper.selectByPrimaryKey(rolePermission.getPid()));
86         }
87          
88         return result;
89     }
90  
91 }
View Code

RolePermissionServiceImpl

 1 package com.how2java.service.impl;
 2  
 3 import java.util.List;
 4  
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Service;
 7  
 8 import com.how2java.mapper.RolePermissionMapper;
 9 import com.how2java.pojo.Permission;
10 import com.how2java.pojo.Role;
11 import com.how2java.pojo.RolePermission;
12 import com.how2java.pojo.RolePermissionExample;
13 import com.how2java.service.RolePermissionService;
14  
15 @Service
16 public class RolePermissionServiceImpl implements RolePermissionService{
17  
18     @Autowired RolePermissionMapper rolePermissionMapper;
19  
20     @Override
21     public void setPermissions(Role role, long[] permissionIds) {
22         //删除当前角色所有的权限
23         RolePermissionExample example= new RolePermissionExample();
24         example.createCriteria().andRidEqualTo(role.getId());
25         List<RolePermission> rps= rolePermissionMapper.selectByExample(example);
26         for (RolePermission rolePermission : rps)
27             rolePermissionMapper.deleteByPrimaryKey(rolePermission.getId());
28  
29         //设置新的权限关系
30         if(null!=permissionIds)
31             for (long pid : permissionIds) {
32                 RolePermission rolePermission = new RolePermission();
33                 rolePermission.setPid(pid);
34                 rolePermission.setRid(role.getId());
35                 rolePermissionMapper.insert(rolePermission);
36             }
37     }
38  
39     @Override
40     public void deleteByRole(long roleId) {
41         RolePermissionExample example= new RolePermissionExample();
42         example.createCriteria().andRidEqualTo(roleId);
43         List<RolePermission> rps= rolePermissionMapper.selectByExample(example);
44         for (RolePermission rolePermission : rps)
45             rolePermissionMapper.deleteByPrimaryKey(rolePermission.getId());
46     }
47  
48     @Override
49     public void deleteByPermission(long permissionId) {
50         RolePermissionExample example= new RolePermissionExample();
51         example.createCriteria().andPidEqualTo(permissionId);
52         List<RolePermission> rps= rolePermissionMapper.selectByExample(example);
53         for (RolePermission rolePermission : rps)
54             rolePermissionMapper.deleteByPrimaryKey(rolePermission.getId());
55     }
56  
57 }
View Code

RoleServiceImpl

 1 package com.how2java.service.impl;
 2  
 3 import java.util.ArrayList;
 4 import java.util.HashSet;
 5 import java.util.List;
 6 import java.util.Set;
 7  
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.stereotype.Service;
10  
11 import com.how2java.mapper.RoleMapper;
12 import com.how2java.mapper.UserRoleMapper;
13 import com.how2java.pojo.Role;
14 import com.how2java.pojo.RoleExample;
15 import com.how2java.pojo.User;
16 import com.how2java.pojo.UserRole;
17 import com.how2java.pojo.UserRoleExample;
18 import com.how2java.service.RoleService;
19 import com.how2java.service.UserService;
20  
21 @Service
22 public class RoleServiceImpl  implements RoleService{
23     @Autowired RoleMapper roleMapper;
24     @Autowired UserRoleMapper userRoleMapper;
25     @Autowired UserService userService;
26  
27     @Override
28     public Set<String> listRoleNames(String userName) {
29         Set<String> result = new HashSet<>();
30         List<Role> roles = listRoles(userName);
31         for (Role role : roles) {
32             result.add(role.getName());
33         }
34         return result;
35     }
36  
37     @Override
38     public List<Role> listRoles(String userName) {
39         List<Role> roles = new ArrayList<>();
40         User user = userService.getByName(userName);
41         if(null==user)
42             return roles;
43          
44         roles = listRoles(user);
45         return roles;
46     }
47      
48     @Override
49     public void add(Role u) {
50         roleMapper.insert(u);
51     }
52   
53     @Override
54     public void delete(Long id) {
55         roleMapper.deleteByPrimaryKey(id);
56     }
57   
58     @Override
59     public void update(Role u) {
60         roleMapper.updateByPrimaryKeySelective(u);
61     }
62   
63     @Override
64     public Role get(Long id) {
65         return roleMapper.selectByPrimaryKey(id);
66     }
67   
68     @Override
69     public List<Role> list(){
70         RoleExample example =new RoleExample();
71         example.setOrderByClause("id desc");
72         return roleMapper.selectByExample(example);
73   
74     }
75  
76     @Override
77     public List<Role> listRoles(User user) {
78         List<Role> roles = new ArrayList<>();
79  
80         UserRoleExample example = new UserRoleExample();
81          
82         example.createCriteria().andUidEqualTo(user.getId());
83         List<UserRole> userRoles= userRoleMapper.selectByExample(example);
84          
85         for (UserRole userRole : userRoles) {
86             Role role=roleMapper.selectByPrimaryKey(userRole.getRid());
87             roles.add(role);
88         }
89         return roles;
90     }  
91      
92 }
View Code

UserRoleServiceImpl

 1 package com.how2java.service.impl;
 2  
 3 import java.util.List;
 4  
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Service;
 7  
 8 import com.how2java.mapper.UserRoleMapper;
 9 import com.how2java.pojo.Role;
10 import com.how2java.pojo.User;
11 import com.how2java.pojo.UserRole;
12 import com.how2java.pojo.UserRoleExample;
13 import com.how2java.service.UserRoleService;
14  
15 @Service
16 public class UserRoleServiceImpl implements UserRoleService{
17  
18     @Autowired UserRoleMapper userRoleMapper;
19     @Override
20     public void setRoles(User user, long[] roleIds) {
21         //删除当前用户所有的角色
22         UserRoleExample example= new UserRoleExample();
23         example.createCriteria().andUidEqualTo(user.getId());
24         List<UserRole> urs= userRoleMapper.selectByExample(example);
25         for (UserRole userRole : urs)
26             userRoleMapper.deleteByPrimaryKey(userRole.getId());
27  
28         //设置新的角色关系
29         if(null!=roleIds)
30             for (long rid : roleIds) {
31                 UserRole userRole = new UserRole();
32                 userRole.setRid(rid);
33                 userRole.setUid(user.getId());
34                 userRoleMapper.insert(userRole);
35             }
36     }
37     @Override
38     public void deleteByUser(long userId) {
39         UserRoleExample example= new UserRoleExample();
40         example.createCriteria().andUidEqualTo(userId);
41         List<UserRole> urs= userRoleMapper.selectByExample(example);
42         for (UserRole userRole : urs) {
43             userRoleMapper.deleteByPrimaryKey(userRole.getId());
44         }
45     }
46     @Override  
47     public void deleteByRole(long roleId) {
48         UserRoleExample example= new UserRoleExample();
49         example.createCriteria().andRidEqualTo(roleId);
50         List<UserRole> urs= userRoleMapper.selectByExample(example);
51         for (UserRole userRole : urs) {
52             userRoleMapper.deleteByPrimaryKey(userRole.getId());
53         }
54     }
55  
56 }
View Code

UserServiceImpl

 1 package com.how2java.service.impl;
 2  
 3 import java.util.List;
 4  
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Service;
 7  
 8 import com.how2java.mapper.UserMapper;
 9 import com.how2java.pojo.User;
10 import com.how2java.pojo.UserExample;
11 import com.how2java.service.UserRoleService;
12 import com.how2java.service.UserService;
13  
14 @Service
15 public class UserServiceImpl  implements UserService{
16  
17     @Autowired UserMapper userMapper;
18     @Autowired UserRoleService userRoleService;
19      
20     @Override
21     public String getPassword(String name) {
22         User user = getByName(name);
23         if(null==user)
24             return null;
25         return user.getPassword();
26     }
27  
28     @Override
29     public User getByName(String name) {
30         UserExample example = new UserExample();
31         example.createCriteria().andNameEqualTo(name);
32         List<User> users = userMapper.selectByExample(example);
33         if(users.isEmpty())
34             return null;
35         return users.get(0);
36     }
37      
38     @Override
39     public void add(User u) {
40         userMapper.insert(u);
41     }
42   
43     @Override
44     public void delete(Long id) {
45         userMapper.deleteByPrimaryKey(id);
46         userRoleService.deleteByUser(id);
47     }
48   
49     @Override
50     public void update(User u) {
51         userMapper.updateByPrimaryKeySelective(u);
52     }
53   
54     @Override
55     public User get(Long id) {
56         return userMapper.selectByPrimaryKey(id);
57     }
58   
59     @Override
60     public List<User> list(){
61         UserExample example =new UserExample();
62         example.setOrderByClause("id desc");
63         return userMapper.selectByExample(example);
64   
65     }
66  
67 }
View Code

Controller 层

LoginController

 1 package com.how2java.controller;
 2 
 3 
 4 import org.apache.shiro.SecurityUtils;
 5 import org.apache.shiro.authc.AuthenticationException;
 6 import org.apache.shiro.authc.UsernamePasswordToken;
 7 import org.apache.shiro.session.Session;
 8 import org.apache.shiro.subject.Subject;
 9 import org.springframework.stereotype.Controller;
10 import org.springframework.ui.Model;
11 import org.springframework.web.bind.annotation.RequestMapping;
12 import org.springframework.web.bind.annotation.RequestMethod;
13 
14 @Controller
15 @RequestMapping("")
16 public class LoginController {
17     @RequestMapping(value="/login",method=RequestMethod.POST) 
18     public String login(Model model,String name, String password) {
19         Subject subject = SecurityUtils.getSubject();  
20         UsernamePasswordToken token = new UsernamePasswordToken(name, password);  
21         try {  
22             subject.login(token);
23             Session session=subject.getSession();
24             session.setAttribute("subject", subject);
25             return "redirect:index";
26             
27         } catch (AuthenticationException e) {  
28             model.addAttribute("error", "验证失败");  
29             return "login"; 
30         }  
31     }
32     
33 
34 
35 }
View Code

PageController

上面已贴

PermissionController

 1 package com.how2java.controller;
 2  
 3 import java.util.List;
 4  
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Controller;
 7 import org.springframework.ui.Model;
 8 import org.springframework.web.bind.annotation.RequestMapping;
 9  
10 import com.how2java.pojo.Permission;
11 import com.how2java.service.PermissionService;
12  
13 @Controller
14 @RequestMapping("config")
15 public class PermissionController {
16     @Autowired PermissionService permissionService;
17      
18     @RequestMapping("listPermission")
19     public String list(Model model){
20         List<Permission> ps= permissionService.list();
21         model.addAttribute("ps", ps);
22         return "listPermission";
23     }
24     @RequestMapping("editPermission")
25     public String list(Model model,long id){
26         Permission permission =permissionService.get(id);
27         model.addAttribute("permission", permission);
28         return "editPermission";
29     }
30     @RequestMapping("updatePermission")
31     public String update(Permission permission){
32  
33         permissionService.update(permission);
34         return "redirect:listPermission";
35     }
36  
37     @RequestMapping("addPermission")
38     public String list(Model model,Permission permission){
39         System.out.println(permission.getName());
40         System.out.println(permission.getDesc_());
41         permissionService.add(permission);
42         return "redirect:listPermission";
43     }
44     @RequestMapping("deletePermission")
45     public String delete(Model model,long id){
46         permissionService.delete(id);
47         return "redirect:listPermission";
48     }   
49  
50 }
View Code

RoleController

 1 package com.how2java.controller;
 2  
 3 import java.util.Arrays;
 4 import java.util.HashMap;
 5 import java.util.List;
 6 import java.util.Map;
 7  
 8 import org.springframework.beans.factory.annotation.Autowired;
 9 import org.springframework.stereotype.Controller;
10 import org.springframework.ui.Model;
11 import org.springframework.web.bind.annotation.RequestMapping;
12  
13 import com.how2java.pojo.Permission;
14 import com.how2java.pojo.Role;
15 import com.how2java.service.PermissionService;
16 import com.how2java.service.RolePermissionService;
17 import com.how2java.service.RoleService;
18  
19 @Controller
20 @RequestMapping("config")
21 public class RoleController {
22     @Autowired RoleService roleService;
23     @Autowired RolePermissionService rolePermissionService;
24     @Autowired PermissionService permissionService;
25      
26     @RequestMapping("listRole")
27     public String list(Model model){
28         List<Role> rs= roleService.list();
29         model.addAttribute("rs", rs);
30          
31         Map<Role,List<Permission>> role_permissions = new HashMap<>();
32          
33         for (Role role : rs) {
34             List<Permission> ps = permissionService.list(role);
35             role_permissions.put(role, ps);
36         }
37         model.addAttribute("role_permissions", role_permissions);
38  
39         return "listRole";
40     }
41     @RequestMapping("editRole")
42     public String list(Model model,long id){
43         Role role =roleService.get(id);
44         model.addAttribute("role", role);
45          
46         List<Permission> ps = permissionService.list();
47         model.addAttribute("ps", ps);
48  
49         List<Permission> currentPermissions = permissionService.list(role);
50         model.addAttribute("currentPermissions", currentPermissions);
51          
52         return "editRole";
53     }
54     @RequestMapping("updateRole")
55     public String update(Role role,long[] permissionIds){
56         rolePermissionService.setPermissions(role, permissionIds);
57         roleService.update(role);
58         return "redirect:listRole";
59     }
60  
61     @RequestMapping("addRole")
62     public String list(Model model,Role role){
63         System.out.println(role.getName());
64         System.out.println(role.getDesc_());
65         roleService.add(role);
66         return "redirect:listRole";
67     }
68     @RequestMapping("deleteRole")
69     public String delete(Model model,long id){
70         roleService.delete(id);
71         return "redirect:listRole";
72     }   
73  
74 }
View Code

UserController

 1 package com.how2java.controller;
 2  
 3 import java.util.HashMap;
 4 import java.util.List;
 5 import java.util.Map;
 6  
 7 import org.apache.shiro.crypto.SecureRandomNumberGenerator;
 8 import org.apache.shiro.crypto.hash.SimpleHash;
 9 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.stereotype.Controller;
11 import org.springframework.ui.Model;
12 import org.springframework.web.bind.annotation.RequestMapping;
13  
14 import com.how2java.pojo.Role;
15 import com.how2java.pojo.User;
16 import com.how2java.service.RoleService;
17 import com.how2java.service.UserRoleService;
18 import com.how2java.service.UserService;
19  
20 @Controller
21 @RequestMapping("config")
22 public class UserController {
23     @Autowired UserRoleService userRoleService;
24     @Autowired UserService userService;
25     @Autowired RoleService roleService;
26      
27     @RequestMapping("listUser")
28     public String list(Model model){
29         List<User> us= userService.list();
30         model.addAttribute("us", us);
31         Map<User,List<Role>> user_roles = new HashMap<>();
32         for (User user : us) {
33             List<Role> roles=roleService.listRoles(user);
34             user_roles.put(user, roles);
35         }
36         model.addAttribute("user_roles", user_roles);
37  
38         return "listUser";
39     }
40     @RequestMapping("editUser")
41     public String edit(Model model,long id){
42         List<Role> rs = roleService.list();
43         model.addAttribute("rs", rs);      
44         User user =userService.get(id);
45         model.addAttribute("user", user);
46          
47         List<Role> roles =roleService.listRoles(user);
48         model.addAttribute("currentRoles", roles);
49          
50         return "editUser";
51     }
52     @RequestMapping("deleteUser")
53     public String delete(Model model,long id){
54         userService.delete(id);
55         return "redirect:listUser";
56     }
57     @RequestMapping("updateUser")
58     public String update(User user,long[] roleIds){
59         userRoleService.setRoles(user,roleIds);
60          
61         String password=user.getPassword();
62         //如果在修改的时候没有设置密码,就表示不改动密码
63         if(user.getPassword().length()!=0) {
64             String salt = new SecureRandomNumberGenerator().nextBytes().toString();
65             int times = 2;
66             String algorithmName = "md5";
67             String encodedPassword = new SimpleHash(algorithmName,password,salt,times).toString();
68             user.setSalt(salt);
69             user.setPassword(encodedPassword);
70         }
71         else
72             user.setPassword(null);
73          
74         userService.update(user);
75  
76         return "redirect:listUser";
77  
78     }
79  
80     @RequestMapping("addUser")
81     public String add(Model model,String name, String password){
82          
83         String salt = new SecureRandomNumberGenerator().nextBytes().toString();
84         int times = 2;
85         String algorithmName = "md5";
86           
87         String encodedPassword = new SimpleHash(algorithmName,password,salt,times).toString();
88          
89         User u = new User();
90         u.setName(name);
91         u.setPassword(encodedPassword);
92         u.setSalt(salt);
93         userService.add(u);
94          
95         return "redirect:listUser";
96     }
97  
98 }
View Code

DatabaseRealm

代码如下:

 1 package com.how2java.realm;
 2  
 3 import java.util.Set;
 4  
 5 import org.apache.shiro.authc.AuthenticationException;
 6 import org.apache.shiro.authc.AuthenticationInfo;
 7 import org.apache.shiro.authc.AuthenticationToken;
 8 import org.apache.shiro.authc.SimpleAuthenticationInfo;
 9 import org.apache.shiro.authc.UsernamePasswordToken;
10 import org.apache.shiro.authz.AuthorizationInfo;
11 import org.apache.shiro.authz.SimpleAuthorizationInfo;
12 import org.apache.shiro.codec.CodecException;
13 import org.apache.shiro.crypto.UnknownAlgorithmException;
14 import org.apache.shiro.crypto.hash.SimpleHash;
15 import org.apache.shiro.realm.AuthorizingRealm;
16 import org.apache.shiro.subject.PrincipalCollection;
17 import org.apache.shiro.util.ByteSource;
18 import org.springframework.beans.factory.annotation.Autowired;
19  
20 import com.how2java.pojo.User;
21 import com.how2java.service.PermissionService;
22 import com.how2java.service.RoleService;
23 import com.how2java.service.UserService;
24  
25 public class DatabaseRealm extends AuthorizingRealm {
26  
27     @Autowired
28     private UserService userService;
29     @Autowired
30     private RoleService roleService;
31     @Autowired
32     private PermissionService permissionService;
33      
34     @Override
35     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
36         //能进入到这里,表示账号已经通过验证了
37         String userName =(String) principalCollection.getPrimaryPrincipal();
38         //通过service获取角色和权限
39         Set<String> permissions = permissionService.listPermissions(userName);
40         Set<String> roles = roleService.listRoleNames(userName);
41          
42         //授权对象
43         SimpleAuthorizationInfo s = new SimpleAuthorizationInfo();
44         //把通过service获取到的角色和权限放进去
45         s.setStringPermissions(permissions);
46         s.setRoles(roles);
47         return s;
48     }
49  
50     @Override
51     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
52         //获取账号密码
53         UsernamePasswordToken t = (UsernamePasswordToken) token;
54         String userName= token.getPrincipal().toString();
55         //获取数据库中的密码
56         User user =userService.getByName(userName);
57         String passwordInDB = user.getPassword();
58         String salt = user.getSalt();
59         //认证信息里存放账号密码, getName() 是当前Realm的继承方法,通常返回当前类名 :databaseRealm
60         //盐也放进去
61         //这样通过applicationContext-shiro.xml里配置的 HashedCredentialsMatcher 进行自动校验
62         SimpleAuthenticationInfo a = new SimpleAuthenticationInfo(userName,passwordInDB,ByteSource.Util.bytes(salt),getName());
63         return a;
64     }
65  
66 }
67 DefaultExceptionHandler
68 代码如下:
69 package com.how2java.exception;
70 
71 import org.apache.shiro.authz.UnauthorizedException;
72 import org.springframework.http.HttpStatus;
73 import org.springframework.web.bind.annotation.ControllerAdvice;
74 import org.springframework.web.bind.annotation.ExceptionHandler;
75 import org.springframework.web.bind.annotation.ResponseStatus;
76 import org.springframework.web.context.request.NativeWebRequest;
77 import org.springframework.web.servlet.ModelAndView;
78 
79 @ControllerAdvice
80 public class DefaultExceptionHandler {
81     @ExceptionHandler({UnauthorizedException.class})
82     @ResponseStatus(HttpStatus.UNAUTHORIZED)
83     public ModelAndView processUnauthenticatedException(NativeWebRequest request, UnauthorizedException e) {
84         ModelAndView mv = new ModelAndView();
85         mv.addObject("ex", e);
86         mv.setViewName("unauthorized");
87         return mv;
88     }
89 }
View Code

DefaultExceptionHandler

 1 package com.how2java.exception;
 2 
 3 import org.apache.shiro.authz.UnauthorizedException;
 4 import org.springframework.http.HttpStatus;
 5 import org.springframework.web.bind.annotation.ControllerAdvice;
 6 import org.springframework.web.bind.annotation.ExceptionHandler;
 7 import org.springframework.web.bind.annotation.ResponseStatus;
 8 import org.springframework.web.context.request.NativeWebRequest;
 9 import org.springframework.web.servlet.ModelAndView;
10 
11 @ControllerAdvice
12 public class DefaultExceptionHandler {
13     @ExceptionHandler({UnauthorizedException.class})
14     @ResponseStatus(HttpStatus.UNAUTHORIZED)
15     public ModelAndView processUnauthenticatedException(NativeWebRequest request, UnauthorizedException e) {
16         ModelAndView mv = new ModelAndView();
17         mv.addObject("ex", e);
18         mv.setViewName("unauthorized");
19         return mv;
20     }
21 }
View Code

http://127.0.0.1:8080/shirossm/config/listUser

http://127.0.0.1:8080/shirossm/index

项目名不一致的话自行修改。

不过此时的权限还是通过注解@RequiresRoles、@RequiresPermissions实现,而非动态url.。之后会在此基础上实现动态url了

基本代码都贴出来了。如有需要demo源码,请留言,互相交流学习乐意分享。

posted @ 2019-10-10 15:27  Kaspar_Choo  阅读(1496)  评论(7编辑  收藏  举报