Spring Security教程(三):自定义表结构
在上一篇博客中讲解了用Spring Security自带的默认数据库存储用户和权限的数据,但是Spring Security默认提供的表结构太过简单了,其实就算默认提供的表结构很复杂,也不一定能满足项目对用户信息和权限信息管理的要求。那么接下来就讲解如何自定义数据库实现对用户信息和权限信息的管理。
一、自定义表结构
这里还是用的mysql数据库,所以pom.xml文件都不用修改。这里只要新建三张表即可,user表、role表、user_role表。其中user用户表,role角色表为保存用户权限数据的主表,user_role为关联表。user用户表,role角色表之间为多对多关系,就是说一个用户可以有多个角色。ER图如下所示:
建表语句:
-- 角色
create table role(
id bigint,
name varchar(50),
descn varchar(200)
);
alter table role add constraint pk_role primary key(id);
alter table role alter column id bigint generated by default as identity(start with 1); -- 用户
create table user(
id bigint,
username varchar(50),
password varchar(50),
status integer,
descn varchar(200)
);
alter table user add constraint pk_user primary key(id);
alter table user alter column id bigint generated by default as identity(start with 1); -- 用户角色连接表
create table user_role(
user_id bigint,
role_id bigint
);
alter table user_role add constraint pk_user_role primary key(user_id, role_id);
alter table user_role add constraint fk_user_role_user foreign key(user_id) references user(id);
alter table user_role add constraint fk_user_role_role foreign key(role_id) references role(id);
插入数据:
insert into user(id,username,password,status,descn) values(1,'admin','admin',1,'管理员');
insert into user(id,username,password,status,descn) values(2,'user','user',1,'用户'); insert into role(id,name,descn) values(1,'ROLE_ADMIN','管理员角色');
insert into role(id,name,descn) values(2,'ROLE_USER','用户角色'); insert into user_role(user_id,role_id) values(1,1);
insert into user_role(user_id,role_id) values(1,2);
insert into user_role(user_id,role_id) values(2,2);
二、修改Spring Security的配置文件(applicationContext.xml)
现在我们要在这样的数据结构基础上使用Spring Security,Spring Security所需要的数据无非就是为了处理两种情况,一是判断登录用户是否合法,二是判断登陆的用户是否有权限访问受保护的系统资源。因此我们所要做的工作就是在现有数据结构的基础上,为Spring Security提供这两种数据。
在jdbc-user-service标签中有这样两个属性:
1. users-by-username-query为根据用户名查找用户,系统通过传入的用户名查询当前用户的登录名,密码和是否被禁用这一状态。
2.authorities-by-username-query为根据用户名查找权限,系统通过传入的用户名查询当前用户已被授予的所有权限。
同时通过代码提示能看到这两个属性的sql语句格式:
从图中可以看到第一个属性要的是通过username来查询用户名、密码和是否可用;第二个属性是通过username来查询用户权限,所以在我们自定义的表结构的基础上对sql语句进行修改,得到如下语句:
select username,password,status as enabled from user where username = ?
select user.username,role.name from user,role,user_role
where user.id=user_role.user_id and
user_role.role_id=role.id and user.username=?
这样最终得到的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
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/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config='true'>
<intercept-url pattern="/adminPage.jsp" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
<!-- 数据源 -->
<beans:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- 此为c3p0在spring中直接配置datasource c3p0是一个开源的JDBC连接池 -->
<beans:property name="driverClass" value="com.mysql.jdbc.Driver" /> <beans:property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/springsecuritydemo?useUnicode=true&characterEncoding=UTF-8" />
<beans:property name="user" value="root" />
<beans:property name="password" value="" />
<beans:property name="maxPoolSize" value="50"></beans:property>
<beans:property name="minPoolSize" value="10"></beans:property>
<beans:property name="initialPoolSize" value="10"></beans:property>
<beans:property name="maxIdleTime" value="25000"></beans:property>
<beans:property name="acquireIncrement" value="1"></beans:property>
<beans:property name="acquireRetryAttempts" value="30"></beans:property>
<beans:property name="acquireRetryDelay" value="1000"></beans:property>
<beans:property name="testConnectionOnCheckin" value="true"></beans:property>
<beans:property name="idleConnectionTestPeriod" value="18000"></beans:property>
<beans:property name="checkoutTimeout" value="5000"></beans:property>
<beans:property name="automaticTestTable" value="t_c3p0"></beans:property>
</beans:bean>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"
users-by-username-query="select username,password,status as enabled from user where username = ?"
authorities-by-username-query="select user.username,role.name from user,role,user_role
where user.id=user_role.user_id and
user_role.role_id=role.id and user.username=?"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
其他的文件和配置和教程二(Spring Security教程(二):通过数据库获得用户权限信息)完全一样,请参考教程二。
三、结果
Spring Security教程(三):自定义表结构的更多相关文章
- Spring Security教程(三)
在上一篇博客中讲解了用Spring Security自带的默认数据库存储用户和权限的数据,但是Spring Security默认提供的表结构太过简单了,其实就算默认提供的表结构很复杂,也不一定能满足项 ...
- spring security方法一 自定义数据库表结构
Spring Security默认提供的表结构太过简单了,其实就算默认提供的表结构很复杂,也无法满足所有企业内部对用户信息和权限信息管理的要求.基本上每个企业内部都有一套自己的用户信息管理结构,同时也 ...
- Spring Security教程(二):自定义数据库查询
Spring Security教程(二):自定义数据库查询 Spring Security自带的默认数据库存储用户和权限的数据,但是Spring Security默认提供的表结构太过简单了,其实就 ...
- Spring Security教程系列(一)基础篇-1
第 1 章 一个简单的HelloWorld 第 1 章 一个简单的HelloWorld Spring Security中可以使用Acegi-1.x时代的普通配置方式,也可以使用从2.0时代才出现的命名 ...
- 【Spring Security】三、自定义数据库实现对用户信息和权限信息的管理
一 自定义表结构 这里还是用的mysql数据库,所以pom.xml文件都不用修改.这里只要新建三张表即可,user表.role表.user_role表.其中user用户表,role角色表为保存用户权限 ...
- Spring Security教程(五):自定义过滤器从数据库从获取资源信息
在之前的几篇security教程中,资源和所对应的权限都是在xml中进行配置的,也就在http标签中配置intercept-url,试想要是配置的对象不多,那还好,但是平常实际开发中都往往是非常多的资 ...
- Spring Security教程(八):用户认证流程源码详解
本篇文章主要围绕下面几个问题来深入源码: 用户认证流程 认证结果如何在多个请求之间共享 获取认证用户信息 一.用户认证流程 上节中提到Spring Security核心就是一系列的过滤器链,当一个请求 ...
- Spring Security(三)
Spring Security(三) 个性化用户认证流程 自定义登录页面 在配置类中指定登录页面和接收登录的 url @Configuration public class BrowserSecuri ...
- Spring Security教程(二):通过数据库获得用户权限信息
上一篇博客中,Spring Security教程(一):初识Spring Security,我把用户信息和权限信息放到了xml文件中,这是为了演示如何使用最小的配置就可以使用Spring Securi ...
随机推荐
- linux下神奇的script
script 是一个神奇命令,script 能够将终端的会话过程录制下来,然后使用 scriptreplay 就可以将其录制的结果播放给他人观看.script 的好处就在于你在终端中的所有操作.敲过的 ...
- WCF 客户端 BasicHttpBinding 兼容 HTTPS 和 HTTP
背景:全站HTTPS的时代来了 全站HTTPS,请参考:http://www.cnblogs.com/bugly/p/5075909.html 1. 设置BasicHttpBinding的BasicH ...
- java 图片与base64相互转化
CreateTime--2017年12月4日17:38:44 Author:Marydon 需要导入: import java.io.FileInputStream; import java.io ...
- Android开发之使用Handler刷新UI控件
一.为什么必须使用Handler 线程安全问题 这个问题要理解的话很容易,如果没有这个约束,那么同时有两个线程对一个UI控件进行调整,那么控件自然就没法正常的工作,而为了解决这种二义性(就是一个东西同 ...
- 粒子滤波跟踪移动机器人(MATLAB Robotics System Toolbox)
MathWorks从MATLAB 2015a开始推出与ROS集成的Robotics System Toolbox(机器人系统工具箱),它为自主移动机器人的研发提供现成的算法和硬件接口. 粒子滤波基本流 ...
- 基于Pygame写的翻译方法
发布时间:2018-11-01 技术:pygame+easygui 概述 实现一个翻译功能,中英文的互相转换.并可以播放翻译后的内容. 翻译接口调用的是百度翻译的api接口. 详细 代码下载: ...
- flex水平垂直居中
<div class="parent"> <div class="children">我是通过flex的水平垂直居中噢!</div ...
- input文本框在div中居中
{display:block;margin-left:auto;margin-right:auto;}
- Android中如何让DialogFragment全屏(DialogFragment fullscreen)
这个问题很让人纠结,因为我要在popopwindows里面使用fragment,但是在popopwindows里面找不到它的父控件,于是转战使用DialogFragment,但是让它全屏是一件很头疼的 ...
- 有可能挑战Java优势的四种技术
2012-02-22 Java是一种杰出的产业开发语言,这是因为它带来了伟大的统一和对事实上以前并不存在的重要标准的关注.但是和所有语言一样,Java将来也会褪色.依据我做的超越Java的研究,一个 ...