使用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",登录后只能看到"添加影片信息"和"修改"操作