使用Spring Security实现方法权限管理

使用Spring Security实现方法权限管理

1、技术目标

了解并创建Security框架所需数据表

为项目添加Spring Security框架

掌握Security框架配置

应用Security框架为项目的CRUD操作绑定权限

2、权限管理需求描述

为系统中的每个操作定义权限,如定义4个权限:

1)超级权限,可以使用所有操作

2)添加影片权限

3)修改影片权限

 4)删除影片权限

为系统设置管理员帐号、密码

为系统创建权限组,每个权限组可以配置多个操作权限,如创建2个权限组:

1)"Administrator"权限组,具有超级权限

 2)"影片维护"权限组,具有添加影片、修改影片权限

可将管理员加入权限组,管理员登录后具备权限组所对应操作权限

管理员可不属于某权限组,可为管理员直接分配权限

3、使用准备

3.1)在数据库中创建6张表

t_admin        管理员帐号表

t_role权限表

t_group        权限组表

t_group_role权限组对应权限表

t_group_user管理员所属权限组表

t_user_role管理员对应权限表

建表SQL语句如下:

Sql代码

SET FOREIGN_KEY_CHECKS=0; 

-- 创建管理员帐号表t_admin 

CREATE TABLE `t_admin` (  

`id`bigint(20) unsigned NOT NULL AUTO_INCREMENT,  

`passwd`varchar(12) NOT NULL DEFAULT '' COMMENT '用户密码',  

`nickname`varchar(20) NOT NULL DEFAULT '' COMMENT '用户名字',  

`phoneno`varchar(32) NOT NULL DEFAULT '' COMMENT '电话号码',  

PRIMARY KEY (`id`)  

) ENGINE=InnoDB AUTO_INCREMENT=6DEFAULT CHARSET=utf8; 

-- 添加3个管理帐号  

INSERT INTO `t_admin` VALUES ('1', 'admin', 'admin', '');  

INSERT INTO `t_admin` VALUES ('4', '123456', 'test', '');  

INSERT INTO `t_admin` VALUES ('5', '111111', '111111', ''); 

-- 创建权限表t_role 

CREATE TABLE `t_role` (  

`id`bigint(20) unsigned NOT NULL AUTO_INCREMENT,  

`role`varchar(40) NOT NULL DEFAULT '',  

`descpt`varchar(40) NOT NULL DEFAULT '' COMMENT '角色描述',  

`category`varchar(40) NOT NULL DEFAULT '' COMMENT '分类',  

PRIMARY KEY (`id`)  

) ENGINE=InnoDB AUTO_INCREMENT=60DEFAULT CHARSET=utf8; 

-- 加入4个操作权限 

INSERT INTO `t_role` VALUES ('1', 'ROLE_ADMIN', '系统管理员', '系统管理员');  

INSERT INTO `t_role` VALUES ('2', 'ROLE_UPDATE_FILM', '修改', '影片管理');  

INSERT INTO `t_role` VALUES ('3', 'ROLE_DELETE_FILM', '删除', '影片管理');  

INSERT INTO `t_role` VALUES ('4', 'ROLE_ADD_FILM', '添加', '影片管理'); 

-- 创建权限组表 

CREATE TABLE `t_group` (  

`id`bigint(20) unsigned NOT NULL AUTO_INCREMENT,  

`groupname`varchar(50) NOT NULL DEFAULT '',  

PRIMARY KEY (`id`)  

) ENGINE=InnoDB AUTO_INCREMENT=7DEFAULT CHARSET=utf8; 

-- 添加2个权限组 

INSERT INTO `t_group` VALUES ('1', 'Administrator');  

INSERT INTO `t_group` VALUES ('2', '影片维护'); 

-- 创建权限组对应权限表t_group_role 

CREATE TABLE `t_group_role` (  

`id`bigint(20) unsigned NOT NULL AUTO_INCREMENT,  

`groupid`bigint(20) unsigned NOT NULL,  

`roleid`bigint(20) unsigned NOT NULL,  

PRIMARY KEY (`id`),  

UNIQUE KEY `groupid2` (`groupid`,`roleid`),  

KEY `roleid` (`roleid`),  

CONSTRAINT `t_group_role_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),  

CONSTRAINT `t_group_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)  

) ENGINE=InnoDB AUTO_INCREMENT=83DEFAULT CHARSET=utf8;  

-- 加入权限组与权限的对应关系 

INSERT INTO `t_group_role` VALUES ('1', '1', '1');  

INSERT INTO `t_group_role` VALUES ('2', '2', '2');  

INSERT INTO `t_group_role` VALUES ('4', '2', '4');  

-- 创建管理员所属权限组表t_group_user 

CREATE TABLE `t_group_user` (  

`id`bigint(20) unsigned NOT NULL AUTO_INCREMENT,  

`userid`bigint(20) unsigned NOT NULL,  

`groupid`bigint(20) unsigned NOT NULL,  

PRIMARY KEY (`id`),  

KEY `userid` (`userid`),  

KEY `groupid` (`groupid`),  

CONSTRAINT `t_group_user_ibfk_2` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),  

CONSTRAINT `t_group_user_ibfk_3` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`)  

) ENGINE=InnoDB AUTO_INCREMENT=18DEFAULT CHARSET=utf8; 

-- 将管理员加入权限组 

INSERT INTO `t_group_user` VALUES ('1', '1', '1');  

INSERT INTO `t_group_user` VALUES ('2', '4', '2'); 

-- 创建管理员对应权限表t_user_role  

-- 设置该表可跳过权限组,为管理员直接分配权限 

CREATE TABLE `t_user_role` (  

`id`bigint(20) unsigned NOT NULL AUTO_INCREMENT,  

`userid`bigint(20) unsigned NOT NULL,  

`roleid`bigint(20) unsigned NOT NULL,  

PRIMARY KEY (`id`),  

KEY `userid` (`userid`),  

KEY `roleid` (`roleid`),  

CONSTRAINT `t_user_role_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`),  

CONSTRAINT `t_user_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)  

) ENGINE=InnoDB AUTO_INCREMENT=5DEFAULT CHARSET=utf8; 

3.2)在项目中新增如下jar包(security框架所需jar包):

spring-security-config-3.1.0.RC2.jar

spring-security-core-3.1.0.RC2.jar

spring-security-taglibs-3.1.0.RC2.jar

spring-security-web-3.1.0.RC2.jar

3.3)创建如下包,放置登录验证过滤器代码:

com.xxx.security

3.4)在src下创建Spring配置文件applicationContext-security.xml,内容如下:

Xml代码

xmlns:b="http://www.springframework.org/schema/beans" xmlns:beans="http://www.springframework.org/schema/beans"  

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-3.0.xsd  

http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 

3.5)在web.xml中加入security配置,如下:

Xml代码

xmlns="http://java.sun.com/xml/ns/javaee"   

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  

contextConfigLocation  

/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml 

springSecurityFilterChain  

org.springframework.web.filter.DelegatingFilterProxy 

springSecurityFilterChain 

org.springframework.web.context.ContextLoaderListener 

7、在com.xxx.security包下创建登录验证过滤器,该过滤器可用于在管理员登录时进行日志记录等相关操作,包括两个类:

LoginUsernamePasswordAuthenticationFilter

LoginSuccessHandler

7.1)LoginUsernamePasswordAuthenticationFilter代码如下:

Java代码

package com.xxx.security;  

import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 

public class LoginUsernamePasswordAuthenticationFilter extends  

        UsernamePasswordAuthenticationFilter { 

7.2)LoginSuccessHandler代码如下:

Java代码

package com.xxx.security; 

import java.io.IOException;  

import javax.servlet.ServletException;  

import javax.servlet.http.HttpServletRequest;  

import javax.servlet.http.HttpServletResponse;  

import org.springframework.security.core.Authentication;  

import org.springframework.security.core.userdetails.UserDetails;  

import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; 

/**

 * 处理管理员登录日志

 *

 */  

public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{ 

@Override  

public void onAuthenticationSuccess(HttpServletRequest request,  

HttpServletResponse response, Authentication authentication)throws IOException,  

            ServletException { 

        UserDetails userDetails = (UserDetails)authentication.getPrincipal(); 

       //输出登录提示信息 

       super.onAuthenticationSuccess(request, response, authentication);  

    } 

8、在applicationContext-security.xml中加入权限管理配置,如下:

Xml代码

xmlns:b="http://www.springframework.org/schema/beans" xmlns:beans="http://www.springframework.org/schema/beans"  

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-3.0.xsd  

http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 

default-target-url="/manager/films.jsp"  

authentication-failure-url="/login.jsp?error=true" /> 

delete-cookies="JSESSIONID" /> 

                直接使用SQL语句查询登录帐号对应权限,  

                users-by-username-query:查询登录用户是否存在  

                authorities-by-username-query:查询登录用户权限(登录用户可以不属于任何组,从t_user_role表中获取权限)  

                group-authorities-by-username-query:查询登录用户所在组的权限 

group-authorities-by-username-query="SELECT g.id,g.groupname,role.role  

                             FROM t_group AS g   

LEFT OUTER JOIN t_group_role AS grouprole ON (g.id = grouprole.groupid)  

LEFT OUTER JOIN t_role AS role ON (role.id = grouprole.roleid)  

LEFT OUTER JOIN t_group_user AS groupuser on (g.id = groupuser.groupid)  

LEFT OUTER JOIN t_admin ON (t_admin.id = groupuser.userid)  

WHEREt_admin.nickname = ?"  

users-by-username-query="SELECT t_admin.nickname AS username,t_admin.passwd as password,'true' AS enabled  

                             FROM t_admin  

WHEREt_admin.nickname = ?"  

authorities-by-username-query="SELECT t_admin.nickname AS username,role.role as authorities  

                               FROM t_admin   

LEFT OUTER JOIN t_user_role AS userrole ON(t_admin.id = userrole.userid)  

LEFT OUTER JOIN t_role AS role ON (userrole.roleid = role.id)  

WHEREt_admin.nickname = ?" /> 

class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  

value="classpath:org/springframework/security/messages" />   

/manager/films.jsp 

/login.jsp?error=true   

9、为影片页面films.jsp定制操作权限,定制后,不同的帐号登录会看到不同的操作,

比如,帐号"admin"属于权限组"Administrator",具备权限"ROLE_ADMIN",登录后

可以看到所有操作,帐号"test"属于权限组"影片维护",具备权限"ROLE_UPDATE_FILM"

和"ROLE_ADD_FILM",登录后只能看到"添加影片信息"和"修改"操作

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容