服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|编程技术|正则表达式|C/C++|

服务器之家 - 编程语言 - JAVA教程 - 详解spring整合shiro权限管理与数据库设计

详解spring整合shiro权限管理与数据库设计

2020-10-27 16:46小爷胡汉三 JAVA教程

这篇文章主要介绍了详解spring整合shiro权限管理与数据库设计,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

之前的文章中我们完成了基础框架的搭建,现在基本上所有的后台系统都逃不过权限管理这一块,这算是一个刚需了。现在我们来集成shiro来达到颗粒化权限管理,也就是从连接菜单到页面功能按钮,都进行权限都验证,从前端按钮的显示隐藏,到后台具体功能方法的权限验证。

首先要先设计好我们的数据库,先来看一张比较粗糙的数据库设计图:

详解spring整合shiro权限管理与数据库设计

具体的数据库设计代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
Navicat MySQL Data Transfer
 
Source Server     : 本机
Source Server Version : 50537
Source Host      : localhost:3306
Source Database    : task
 
Target Server Type  : MYSQL
Target Server Version : 50537
File Encoding     : 65001
 
Date: 2017-01-19 09:58:27
*/
 
SET FOREIGN_KEY_CHECKS=0;
 
-- ----------------------------
-- Table structure for sys_authority
-- ----------------------------
DROP TABLE IF EXISTS `sys_authority`;
CREATE TABLE `sys_authority` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
 `data_url` varchar(100) NOT NULL COMMENT '连接路径或方法',
 `menu_class` varchar(50) NOT NULL COMMENT '菜单样式',
 `menu_code` varchar(50) NOT NULL COMMENT '菜单编码',
 `menu_name` varchar(50) NOT NULL COMMENT '菜单名称',
 `parent_menucode` varchar(50) DEFAULT NULL COMMENT '上级菜单编码',
 `sequence` bigint(20) DEFAULT '0' COMMENT '排序',
 `menu_type` varchar(2) DEFAULT '1' COMMENT '菜单类型(1是左导航菜单 2是按钮权限)',
 `create_time` varchar(30) NOT NULL COMMENT '创建时间',
 PRIMARY KEY (`id`),
 UNIQUE KEY `uk_sys_authority_menu_code` (`menu_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单表';
 
-- ----------------------------
-- Records of sys_authority
-- ----------------------------
 
-- ----------------------------
-- Table structure for sys_department
-- ----------------------------
DROP TABLE IF EXISTS `sys_department`;
CREATE TABLE `sys_department` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
 `department_key` varchar(20) NOT NULL COMMENT '部门编码',
 `department_value` varchar(40) NOT NULL COMMENT '部门名称',
 `description` varchar(200) DEFAULT NULL COMMENT '描述',
 `parent_departmentkey` varchar(20) DEFAULT NULL COMMENT '上级部门编码',
 `create_time` varchar(30) DEFAULT NULL COMMENT '创建时间',
 PRIMARY KEY (`id`),
 UNIQUE KEY `uk_sys_department_department_key` (`department_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='部门表';
 
-- ----------------------------
-- Records of sys_department
-- ----------------------------
 
-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
 `role_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
 `role_key` varchar(30) DEFAULT NULL COMMENT '角色编码',
 `create_time` varchar(30) DEFAULT NULL COMMENT '创建时间',
 `description` varchar(200) DEFAULT NULL COMMENT '描述',
 `role_value` varchar(40) NOT NULL COMMENT '角色名称',
 `company_id` bigint(20) DEFAULT NULL,
 PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='角色表';
 
-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT INTO `sys_role` VALUES ('1', 'ROLE_USER', null, null, '', null);
INSERT INTO `sys_role` VALUES ('2', 'ROLE_ADMIN', null, null, '', null);
 
-- ----------------------------
-- Table structure for sys_role_authority
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_authority`;
CREATE TABLE `sys_role_authority` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键编号自增长',
 `menu_code` varchar(50) NOT NULL COMMENT '菜单编码',
 `role_key` varchar(40) NOT NULL COMMENT '角色编码',
 `menu_type` int(11) DEFAULT NULL COMMENT '菜单类型 1 导航 2 按钮',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色菜单表';
 
-- ----------------------------
-- Records of sys_role_authority
-- ----------------------------
 
-- ----------------------------
-- Table structure for sys_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission` (
 `role_id` int(11) NOT NULL COMMENT '角色主键编号',
 `permissions` varchar(1000) DEFAULT NULL COMMENT '按钮权限',
 KEY `FK9q28ewrhntqeipl1t04kh1be7` (`role_id`),
 CONSTRAINT `FK9q28ewrhntqeipl1t04kh1be7` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`role_id`),
 CONSTRAINT `fk_sys_role_permission_role_id` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色按钮权限表';
 
-- ----------------------------
-- Records of sys_role_permission
-- ----------------------------
 
-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
 `user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
 `login_account` varchar(30) NOT NULL COMMENT '登录账号',
 `login_pass` varchar(65) NOT NULL COMMENT '登录密码',
 `user_name` varchar(20) DEFAULT NULL COMMENT '昵称',
 `user_head` varchar(30) DEFAULT NULL COMMENT '头像',
 `user_phone` varchar(20) DEFAULT NULL COMMENT '手机',
 `user_email` varchar(30) DEFAULT NULL COMMENT '邮箱',
 `user_sex` int(11) DEFAULT NULL COMMENT '性别',
 `user_birthday` varchar(30) DEFAULT NULL COMMENT '生日',
 `register_time` varchar(30) NOT NULL COMMENT '注册时间',
 `department_key` varchar(20) DEFAULT NULL COMMENT '部门编码',
 PRIMARY KEY (`user_id`),
 UNIQUE KEY `uk_sys_user_login_account` (`login_account`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='用户表';
 
-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('2', 'hzw2312', '63cbbfefc6a5f389ea64299134e989a9a378d1293cad8b5623331bf5d0e023a9', null, null, null, 'hzw2312@sina.com', null, null, '2017-01-18 14:39:23', null);
INSERT INTO `sys_user` VALUES ('3', 'hzw2312f', '63cbbfefc6a5f389ea64299134e989a9a378d1293cad8b5623331bf5d0e023a9', null, null, null, 'hzw23d12@sina.com', null, null, '2017-01-18 15:25:08', null);
INSERT INTO `sys_user` VALUES ('4', 'hhsykx', '63cbbfefc6a5f389ea64299134e989a9a378d1293cad8b5623331bf5d0e023a9', null, null, null, 'hhs2312@sina.com', null, null, '2017-01-18 15:25:47', null);
 
-- ----------------------------
-- Table structure for sys_user_role
-- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
 `user_id` bigint(20) NOT NULL COMMENT '用户编号',
 `role_id` int(20) NOT NULL COMMENT '角色编号',
 PRIMARY KEY (`user_id`,`role_id`),
 KEY `FKhh52n8vd4ny9ff4x9fb8v65qx` (`role_id`),
 CONSTRAINT `FKb40xxfch70f5qnyfw8yme1n1s` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`user_id`),
 CONSTRAINT `FKhh52n8vd4ny9ff4x9fb8v65qx` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`role_id`),
 CONSTRAINT `fk_sys_user_role_role_id` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`role_id`),
 CONSTRAINT `fk_sys_user_role_user_id` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户角色映射表';
 
-- ----------------------------
-- Records of sys_user_role
-- ----------------------------
INSERT INTO `sys_user_role` VALUES ('3', '1');
INSERT INTO `sys_user_role` VALUES ('4', '1');
INSERT INTO `sys_user_role` VALUES ('2', '2');

下面我们开始根据之前的框架集成shiro

首先在pom.xml添加shiro的支持,先在properties中声明一下要倒入的版本:

?
1
2
3
4
<properties>
  <shiro.version>1.3.2</shiro.version>
  <commons-logging.version>1.2</commons-logging.version>
</properties>

然后在是dependency的添加:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- shiro权限 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-all</artifactId>
      <version>${shiro.version}</version>
    </dependency>
     
    <!-- commons-logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>${commons-logging.version}</version>
    </dependency>

下面是shiro的配置跟spring配置放在同级目录spring-shiro.xml:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
   
   
  <!-- 缓存管理器 使用Ehcache实现 -->
  <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />
  </bean>
   
  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!--认证管理器-->
    <property name="realm" ref="shiroSecurityRealm" />
    <!-- 缓存管理器 -->
    <property name="cacheManager" ref="cacheManager" />
    <!-- rememberMe管理器 -->
    <property name="rememberMeManager" ref="rememberMeManager"/>
  </bean>
  <!-- 会话ID生成器 -->
  <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
 
  <!-- 会话Cookie模板 -->
  <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    <constructor-arg value="sid"/>
    <property name="httpOnly" value="true"/>
    <property name="maxAge" value="-1"/>
  </bean>
   
  <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"
    <constructor-arg value="rememberMe"/> 
    <property name="httpOnly" value="true"/>
    <property name="maxAge" value="2592000"/><!-- 30天 -->
  </bean>
  <!-- rememberMe管理器 -->
  <bean id="rememberMeManager"
    class="org.apache.shiro.web.mgt.CookieRememberMeManager"
    <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('7gzYfKjTASKdsai43ds==')}"/> 
     <property name="cookie" ref="rememberMeCookie"/>
  </bean>
   
  <!-- 会话DAO -->
  <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
    <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
    <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
  </bean>
  <!-- 会话验证调度器 -->
  <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
    <property name="sessionValidationInterval" value="3000000"/>
    <property name="sessionManager" ref="sessionManager"/>
  </bean>
 
  <!-- 会话管理器 -->
  <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <property name="globalSessionTimeout" value="3000000"/>
    <property name="deleteInvalidSessions" value="true"/>
    <property name="sessionValidationSchedulerEnabled" value="true"/>
    <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
    <property name="sessionDAO" ref="sessionDAO"/>
    <property name="sessionIdCookieEnabled" value="true"/>
    <property name="sessionIdCookie" ref="sessionIdCookie"/>
  </bean>
   
  <bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"
    <property name="rememberMeParam" value="rememberMe"/> 
  </bean>
   
   
  <bean id="sysUserFilter" class="yfkj.gz.task.security.SysUserFilter"/>
   
  <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/login.jsp"/>
    <property name="successUrl" value="/page/main.action"/>
    <property name="filters">
      <util:map>
        <entry key="authc">
          <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/>
        </entry>
        <entry key="sysUser" value-ref="sysUserFilter"/>
      </util:map>
    </property>
    <property name="filterChainDefinitions">
      <value>
        /static/** = anon
        /login.jsp = anon
        /sysuser/login.action = anon
        /sysuser/register.action = anon
        /sysuser/getEMailCount.action = anon
        /sysuser/getUserNameCount.action = anon
        /sysuser/logout.action = logout
        /** = user,sysUser <!-- 表示访问该地址的用户是身份验证通过或RememberMe登录的都可以 -->
        <!-- /** = authc 表示访问该地址用户必须身份验证通过-->
      </value>
    </property>
  </bean>
   
  <!-- Post processor that automatically invokes init() and destroy() methods -->
  <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
   
</beans>

上面的

/static/** = anon,/login.jsp = anon...这些等于anon的就是默认不做权限验证的,我们的登录,注册,静态资源等,不需要权限验证。

权限缓存的配置(如果不用缓存的话,每次请求都要去访问数据库查询权限)ehcache-shiro.xml:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="shirocache">
 
  <diskStore path="java.io.tmpdir/yfkj-shiro-ehcache"/>
   
  <!-- 默认缓存 -->
  <defaultCache maxElementsInMemory="1000" eternal="false"
    overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="180"
    diskPersistent="false" diskExpiryThreadIntervalSeconds="120" />
   
  <!-- 登录记录缓存 -->
  <cache name="passwordRetryCache"
      maxEntriesLocalHeap="2000"
      eternal="false"
      timeToIdleSeconds="3600"
      timeToLiveSeconds="0"
      overflowToDisk="false"
      statistics="true">
  </cache>
 
  <!-- 授权缓存 -->
  <cache name="authorizationCache"
      maxEntriesLocalHeap="2000"
      eternal="false"
      timeToIdleSeconds="3600"
      timeToLiveSeconds="0"
      overflowToDisk="false"
      statistics="true">
  </cache>
 
  <!-- 认证缓存 -->
  <cache name="authenticationCache"
      maxEntriesLocalHeap="2000"
      eternal="false"
      timeToIdleSeconds="3600"
      timeToLiveSeconds="0"
      overflowToDisk="false"
      statistics="true">
  </cache>
 
  <cache name="shiro-activeSessionCache"
      maxEntriesLocalHeap="2000"
      eternal="false"
      timeToIdleSeconds="3600"
      timeToLiveSeconds="0"
      overflowToDisk="false"
      statistics="true">
  </cache>
   
  <cache name="shiro-kickout-session"
      maxEntriesLocalHeap="2000"
      eternal="false"
      timeToIdleSeconds="3600"
      timeToLiveSeconds="0"
      overflowToDisk="false"
      statistics="true">
  </cache>
 
</ehcache>

自定义用户过滤类SysUserFilter:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import yfkj.gz.task.service.ISysUserService;
 
import org.apache.shiro.web.filter.PathMatchingFilter;
 
import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
 
/**
 * 自定义用户过滤器
 * @author 胡汉三
 *
 */
public class SysUserFilter extends PathMatchingFilter {
   
  @Resource
  private ISysUserService sysUserService;
 
  @Override
  protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
    //可以参考http://jinnianshilongnian.iteye.com/blog/2025656
    return true;
  }
}

权限认证类ShiroSecurityRealm:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import javax.annotation.Resource;
 
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.Sha256CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;
 
import yfkj.gz.task.dao.ISysUserDao;
import yfkj.gz.task.entity.SysRole;
import yfkj.gz.task.entity.SysUser;
import yfkj.gz.task.service.ISysUserService;
 
/**
 * 权限认证
 * @author 胡汉三
 * @date  2017年1月19日 上午10:52:17
 */
@SuppressWarnings("deprecation")
@Component
public class ShiroSecurityRealm extends AuthorizingRealm {
   
  @Resource
  private ISysUserService userService;
 
  @Resource
  private ISysUserDao sysUserDao;
 
  public ShiroSecurityRealm() {
    setName("ShiroSecurityRealm"); // This name must match the name in the SysUser class's getPrincipals() method
    setCredentialsMatcher(new Sha256CredentialsMatcher());
  }
 
  /**
   * 登录认证
   */
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
    UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
    SysUser user = userService.getByProerties(new String[]{"loginAccount"}, new String[]{token.getUsername()},null);
    if (user != null) {
      return new SimpleAuthenticationInfo(user.getUserId(), user.getLoginPass(), getName());
    } else {
      return null;
    }
  }
 
 
  /**
   * 权限认证
   */
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    Long userId = (Long) principals.fromRealm(getName()).iterator().next();
    SysUser user = userService.get(userId);
    if (user != null) {
      SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      for (SysRole role : user.getRoles()) {
        info.addRole(role.getRoleKey());
        info.addStringPermissions(role.getPermissions());
      }
      return info;
    } else {
      return null;
    }
  }
 
}

在web.xml加入:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 加载spring配置文件 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml,classpath:spring-hibernate.xml,classpath:spring-shiro.xml</param-value>
  </context-param>
   
  <!-- shiro权限过滤器 -->
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
      <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>

在登录方法中加上权限的登录(构造方法参数:登录账号,登录密码,记住我):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//存入session
    Subject subject = SecurityUtils.getSubject();
    //记得传入明文密码
    subject.login(new UsernamePasswordToken(userInfo.getLoginAccount(), user.getLoginPass(), rememberMe));
完整的登录方法:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
/**
   * 用户登录
   * @param response
   * @param user
   * @throws IOException
   */
  @RequestMapping(value = "/login", method = { RequestMethod.POST, RequestMethod.GET })
  public void login(SysUser user,boolean rememberMe) throws IOException{
    //用户登录
    SysUser userInfo = userService.getByProerties(new String[]{"loginAccount"}, new String[]{user.getLoginAccount()},null);
    if(userInfo==null){
      result.setMessage("用户名错误");
      super.writeJSON(result);
      return;
    }
    if(!userInfo.getLoginPass().equals(new Sha256Hash(user.getLoginPass()).toHex())){
      result.setMessage("密码错误");
      super.writeJSON(result);
      return;
    }
    //存入session
    Subject subject = SecurityUtils.getSubject();
    //记得传入明文密码
    subject.login(new UsernamePasswordToken(userInfo.getLoginAccount(), user.getLoginPass(), rememberMe));
    session.setAttribute(USER_SESSION, userInfo);
    result.setMessage("登录成功");
    result.setSuccess(true);
    super.writeJSON(result);
  }

数据库也设计好啦,该整合的也整合了,怎么来实现呢,这里先说一点点,详细的等下一篇说:

jsp页面引入page指令:

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

在要做验证的按钮上加上shiro标签的判断:

?
1
2
3
4
5
<shiro:hasPermission name="${ROLE_KEY}:role:role_add">
          <button id="btn_add" type="button" class="btn btn-default">
            <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增
          </button>
          </shiro:hasPermission>

${ROLE_KEY}:role:role_add的意思就是:

${ROLE_KEY}角色

role是指菜单(页面)

role_add指的功能

联合起来就是,当前角色在role菜单(页面)中有没有role_add新增的功能,如果有就会显示,没有就不显示这个按钮啦。

在后台方法中验证:

在对应的方法中加入代码:

?
1
2
Subject subject = SecurityUtils.getSubject();
subject.checkPermission(getCurrentRoleKey()+":role:role_add");

如果没有通过checkPermission,则会直接返回错误,不执行下面的代码啦。

实体Base类BaseEntity:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
 
/**
 * 实体父类
 * @author 胡汉三
 * @date  2017年1月18日 上午11:03:11
 */
public class BaseEntity implements Serializable{
   
  /**
   *
   */
  private static final long serialVersionUID = 3730369554400423966L;
   
  /**
   * 排序
   */
  private Map<String, String> sortedConditions = new LinkedHashMap<String, String>();
 
  public Map<String, String> getSortedConditions() {
    return sortedConditions;
  }
  public void setSortedConditions(Map<String, String> sortedConditions) {
    this.sortedConditions = sortedConditions;
  }
   
   
}

用户实体SysUser:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import java.util.HashSet;
import java.util.Set;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
 
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
 
import yfkj.gz.support.BaseEntity;
 
 
/**
 * 用户的实体类
 */
@Entity
@Table(name = "sys_user")
public class SysUser extends BaseEntity{
 
  /**
   *
   */
  private static final long serialVersionUID = 2491111485758197830L;
   
  /**主键**/
  @Id
  @GeneratedValue
  @Column(name = "user_id")
  private Long userId;
 
  /**登录账号**/
  @Column(name = "login_account" ,length = 30 , unique = true )
  private String loginAccount;
 
  /**登录密码**/
  @Column(name = "login_pass" ,length = 65)
  private String loginPass;
 
  /**昵称**/
  @Column(name = "user_name" ,length = 20)
  private String userName;
 
  /**头像**/
  @Column(name = "user_head" ,length = 30)
  private String userHead;
 
  /**手机**/
  @Column(name = "user_phone" ,length = 20)
  private String userPhone;
 
  /**邮箱**/
  @Column(name = "user_email" ,length = 30)
  private String userEmail;
 
  /**性别**/
  @Column(name = "user_sex")
  private Integer userSex;
 
  /**生日**/
  @Column(name = "user_birthday" ,length = 30)
  private String userBirthday;
 
  /**注册时间**/
  @Column(name = "register_time" ,length = 30)
  private String registerTime;
   
  /**部门编码**/
  @Column(name = "department_key" ,length = 20)
  private String departmentKey;
   
   
  /**用户角色**/
  @ManyToMany(fetch = FetchType.EAGER)
  @JoinTable(name = "sys_user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") })
  @Cache(region = "all", usage = CacheConcurrencyStrategy.READ_WRITE)
  private Set<SysRole> roles = new HashSet<SysRole>();
   
   
  /**get/set**/
   
 
  /**主键**/
  public Long getUserId(){
    return userId;
  }
  /**主键**/
  public void setUserId(Long userId){
    this.userId= userId;
  }
  /**登录账号**/
  public String getLoginAccount(){
    return loginAccount;
  }
  /**登录账号**/
  public void setLoginAccount(String loginAccount){
    this.loginAccount= loginAccount;
  }
  /**登录密码**/
  public String getLoginPass(){
    return loginPass;
  }
  /**登录密码**/
  public void setLoginPass(String loginPass){
    this.loginPass= loginPass;
  }
  /**昵称**/
  public String getUserName(){
    return userName;
  }
  /**昵称**/
  public void setUserName(String userName){
    this.userName= userName;
  }
  /**头像**/
  public String getUserHead(){
    return userHead;
  }
  /**头像**/
  public void setUserHead(String userHead){
    this.userHead= userHead;
  }
  /**手机**/
  public String getUserPhone(){
    return userPhone;
  }
  /**手机**/
  public void setUserPhone(String userPhone){
    this.userPhone= userPhone;
  }
  /**邮箱**/
  public String getUserEmail(){
    return userEmail;
  }
  /**邮箱**/
  public void setUserEmail(String userEmail){
    this.userEmail= userEmail;
  }
  /**性别**/
  public Integer getUserSex(){
    return userSex;
  }
  /**性别**/
  public void setUserSex(Integer userSex){
    this.userSex= userSex;
  }
  /**生日**/
  public String getUserBirthday(){
    return userBirthday;
  }
  /**生日**/
  public void setUserBirthday(String userBirthday){
    this.userBirthday= userBirthday;
  }
  /**注册时间**/
  public String getRegisterTime(){
    return registerTime;
  }
  /**注册时间**/
  public void setRegisterTime(String registerTime){
    this.registerTime= registerTime;
  }
   
  public Set<SysRole> getRoles() {
    return roles;
  }
  public void setRoles(Set<SysRole> roles) {
    this.roles = roles;
  }
   
   
}

角色实体SysRole:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import java.util.Set;
 
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;
 
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
 
 
import yfkj.gz.support.BaseEntity;
 
/**
 * 角色的实体类
 */
@Entity
@Table(name = "sys_role")
@Cache(region = "all", usage = CacheConcurrencyStrategy.READ_WRITE)
public class SysRole extends BaseEntity{
 
  // 各个字段的含义请查阅文档的数据库结构部分
  private static final long serialVersionUID = 6019103858711599150L;
  @Id
  @GeneratedValue
  @Column(name = "role_id")
  private Long roleId;
  @Column(name = "role_key", length = 40, nullable = false, unique = true)
  private String roleKey;
  @Column(name = "role_value", length = 40, nullable = false)
  private String roleValue;
  @Column(name = "create_time", length = 30)
  private String createTime;
  @Column(name = "description", length = 200)
  private String description;
   
  @ElementCollection
  @JoinTable(name = "sys_role_permission", joinColumns = { @JoinColumn(name = "role_id") })
  @Cache(region = "all", usage = CacheConcurrencyStrategy.READ_WRITE)
  private Set<String> permissions;
 
  @Column(name="company_id")
  private Long companyId;
   
  public SysRole() {
 
  }
 
   
 
  public Long getRoleId() {
    return roleId;
  }
 
  public void setRoleId(Long roleId) {
    this.roleId = roleId;
  }
 
  public String getRoleKey() {
    return roleKey;
  }
 
  public void setRoleKey(String roleKey) {
    this.roleKey = roleKey;
  }
 
  public String getRoleValue() {
    return roleValue;
  }
 
  public void setRoleValue(String roleValue) {
    this.roleValue = roleValue;
  }
 
  public String getCreateTime() {
    return createTime;
  }
 
  public void setCreateTime(String createTime) {
    this.createTime = createTime;
  }
   
  public String getDescription() {
    return description;
  }
 
  public void setDescription(String description) {
    this.description = description;
  }
 
  public Set<String> getPermissions() {
    return permissions;
  }
 
  public void setPermissions(Set<String> permissions) {
    this.permissions = permissions;
  }
 
  public Long getCompanyId() {
    return companyId;
  }
 
  public void setCompanyId(Long companyId) {
    this.companyId = companyId;
  }
 
}

项目结构图:

详解spring整合shiro权限管理与数据库设计

源码地址:spring-shiro.rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://blog.csdn.net/hzw2312/article/details/54612962

延伸 · 阅读

精彩推荐