Spring Security进阶身份认证之使用数据库中的用户进行身份认证(附源码)

    在上一篇HelloSpringSecurity一文中,我们使用了静态账号和密码的方式完成了身份认证。本文在上一篇博文的基础上,将使用数据库中的用户进行身份认证。从本文中你将会看到Spring Security使用数据库中的用户进行身份认证依然是非常简单的事情。


    1. 在pom.xml中添加mysql数据库驱动与c3p0数据源的相关的依赖。


 <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.21</version>
 </dependency>
<dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
 </dependency>


    2. 准备MySQL数据库及相关数据。


    本例子使用到user(用户表)、role(角色表)和user_role(用户角色表)三个表,表之间的关系如下:


wKioL1TBtlex1oMgAACUVwD_IMc921.jpg


    为了方便大家进行测试,建表的语句如下:


/*
Navicat MySQL Data Transfer

Source Server         : 10.0.0.12
Source Server Version : 50619
Source Host           : 10.0.0.12:3305
Source Database       : favsecurity

Target Server Type    : MYSQL
Target Server Version : 50619
File Encoding         : 65001

Date: 2015-01-23 10:28:39
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` int(11) NOT NULL DEFAULT '0' COMMENT 'id',
  `name` varchar(50) DEFAULT NULL COMMENT 'name',
  `descn` varchar(50) DEFAULT NULL COMMENT 'descn',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色表';

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', 'ROLE_ADMIN', '管理员角色');
INSERT INTO `role` VALUES ('2', 'ROLE_USER', '用户角色');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL DEFAULT '0' COMMENT 'id',
  `username` varchar(50) DEFAULT NULL COMMENT 'username',
  `password` varchar(50) DEFAULT NULL COMMENT 'password',
  `status` varchar(1024) DEFAULT NULL COMMENT 'status',
  `descn` varchar(1024) DEFAULT NULL COMMENT 'descd',
  PRIMARY KEY (`id`),
  KEY `AK_Key_1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admin', 'admin', '1', '管理\r\n员');
INSERT INTO `user` VALUES ('2', 'user', 'user', '1', '用户\r\n');
INSERT INTO `user` VALUES ('3', 'favccxx', 'favboy', '1', '帅锅');

-- ----------------------------
-- Table structure for user_role
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `user_id` int(11) DEFAULT NULL COMMENT '用户表_id',
  `role_id` int(11) DEFAULT NULL COMMENT '角色表_id',
  KEY `FK_FK_USER_ROLE_ROLE` (`role_id`),
  KEY `FK_FK_USER_ROLE_USER` (`user_id`),
  CONSTRAINT `FK_FK_USER_ROLE_USER` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
  CONSTRAINT `FK_FK_USER_ROLE_ROLE` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户角色表';

-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES ('1', '1');
INSERT INTO `user_role` VALUES ('1', '2');
INSERT INTO `user_role` VALUES ('2', '2');
INSERT INTO `user_role` VALUES ('3', '1');
INSERT INTO `user_role` VALUES ('3', '2');

        
    3. 修改springSecurity.xml,更改security:authentication-provider提供的用户访问机制。


<security:authentication-manager>

  <security:authentication-provider>

   <security:user-service>

    <security:user name="favccxx" password="favccxx" authorities="ROLE_USER,ROLE_ADMIN"/>

    <security:user name="super" password="super" authorities="ROLE_SUPERADMIN"/>

   </security:user-service>

  </security:authentication-provider>

 </security:authentication-manager>


     将上面的灰色划掉的部分更改为下面绿色的部分。


<security:authentication-manager>

  <security:authentication-provider>

       <security:jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password,1 as enabled from user WHERE username=?"

        authorities-by-username-query="select u.username, r.name as role from user u,user_role ur, role r where u.id=ur.user_Id and r.id = ur.role_Id and u.username=?"/>

      </security:authentication-provider>

 </security:authentication-manager>


    备注:dataSource在springdb.xml中定义,在springSecurity.xml中引用springdb.xml即可。springdb.xml相关的文件如下:


    springdb.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	 xmlns:tx="http://www.springframework.org/schema/tx"
	 xmlns:aop="http://www.springframework.org/schema/aop"
	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.0.xsd
	      http://www.springframework.org/schema/tx
	    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
	">
	
	<context:property-placeholder location="classpath:database.properties"/>
	
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
		<property name="driverClass">
			<value>${dataSource.driverClassName}</value>
		</property>
		<property name="jdbcUrl">
			<value>${dataSource.url}</value>
		</property>
		<property name="user">
			<value>${dataSource.username}</value>
		</property>
		<property name="password">
			<value>${dataSource.password}</value>
		</property>

		<!-- 最大连接数 -->
		<property name="maxPoolSize">
			<value>${dataSource.c3p0.max_size}</value>
		</property>

		<!-- 最小连接数 -->
		<property name="minPoolSize">
			<value>${dataSource.c3p0.min_size}</value>
		</property>

		<!-- 最大空闲时间,超时未被使用则连接被抛弃,单位毫秒 -->
		<property name="maxIdleTime">
			<value>${dataSource.c3p0.max_idle_time}</value>
		</property>

		<!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 -->
		<!-- 
		<property name="checkoutTimeout">
			<value>${dataSource.c3p0.checkout_timeout}</value>
		</property>
 		-->

		<!-- 最大的PreparedStatement的数量 -->
		<property name="maxStatements">

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
我们先手动制作一个可以ssh登录的容器,然后按照操作步骤编写Dockerfile,用docker build根据Dockerfile创建镜像,最后我们可以用这个镜像来生成可ssh登录的容器了。 一、首先创建一个容器并登入 [root@localhost~]#dockerimagescentosREPOSITORYTAGIMAGEIDCREATEDVIRTUALSIZEcentoscentos7ae0c2d0bdc104weeksago224MBcentoslatestae0c2d0bdc104weeksa
从一个存在的库,抽取其表结构,对象,权限等,再部署成一个不包含数据的”空库“的方法有很多种。如自带的Generate Scripts功能,自定义脚本提取创建脚本等。 在实际使用中,我更喜欢使用DAC的方式。特别是它能跟PowerShell结合使用。 什么是DAC,它能干什么? 数据层应用程序 (DAC) 可以简化支持客户端-服务器或多层应用程序的数据层元素的开发、部署和管理。每个 DAC 都作为单个管理单元运行,贯穿于关联应用程序的开发、测试和生产生命周期。DAC 定义支持应用程序所需的所有数据库对象(如
一、GO语言的类型 GO语言中内置了如下基础类型: 整型:byte(int8)、int16、int、uint等 浮点型:float32、float64 复数类型:complex64、complex128 布尔类型:bool 字符类型:rune 字符串:string 错误类型:error 同时GO语言也支持下面的复合类型: 指针 数组 切片:slice 集合:map 通道:chan 结构体:struct 接口:interface 上看下看左看右看,怎么 没有看到double类型 呢?同时还有几个陌生的面孔,
问题描述: 在生产环境中,当辅助副本成员的读压力很大时,可通过添加新的辅助副本成员来缓解压力。 为了能实现主副本成员不停机,并减轻主副本成员的压力,可在辅助副本成员上mongodump备份数据; 为了实现新的辅助副本成员的快速恢复,可直接通过以NFS方式挂载辅助副本成员到做备份操作的辅助副本成员上; 为了保证数据的一致性,在mongodump数据的时候使用—oplog参数,mongorestore时使用—oplogReplay参数; 为了满足后期空间的扩容,通过—directoryperdb参数将数据库分

hadoop jetty的应用 - 2015-03-18 09:03:02

在hadoop中很多地方都用到了servlet,并且使用jetty作为servlet的容器来提供http的服务,其主要是通过org.apache.hadoop.http.HttpServer类实现的,HttpServer类是对Jetty的简单封装,通过调用HttpServer类的addServlet方法增加可以实现增加servlet到jetty的功能: publicvoidaddServlet(Stringname,StringpathSpec,Class?extendsHttpServletclazz)

使用zabbix全方位监控MySQL - 2015-03-18 06:03:05

上一篇文章 使用zabbix自带MySQL监控模板监控MySQL 对MySQL的监控不够详细。本文继续探讨对MySQL的详细监控,包括MySQL实例,MySQL主从复制和MySQL存储引擎等。 本文使用的MySQL版本是5.5 本文使用的模板主要通过FROMDUAL提供的模板更改而成,FROMDUAL官方使用Perl语言编写采集脚本然后通过zabbix trapper的方式推送数据到zabbix server。我觉得FROMDUAL官方提供的配置方式繁琐,并且我对Perl语言又不熟悉,于是阅读官方的Per
本文 首发于 烂泥行天下 公司服务器比较多,需要把apache源码包制作成rpm包,然后放到公司内网yum源上进行下载安装。apache的rpm包安装方式比源码安装方式比较快,这能节约不少的时间。 有关内网yum源的搭建,可以参考《 烂泥:yum的使用及配置 》这篇文章。 一、安装rpm-build 查阅相关资料得知,要把源码包制作成rpm包需要使用rpm打包工具rpm-build。 rpm-build通过rpmbuild命令根据本地源码包,通过spec文件中的规则就可以把源码包制作成rpm包。 现在我们
今天qq群里有朋友讨论使用ansible创建mysql主从的问题,正好我公司之前有需求,我就写了这个模块,现在分享给大家。 一、各软件版本 1、docker版本 Clientversion:1.3.2ClientAPIversion:1.15Goversion(client):go1.3.3Gitcommit(client):39fa2fa/1.3.2OS/Arch(client):linux/amd64Serverversion:1.3.2ServerAPIversion:1.15Goversion(s
MySQL 有一个和优秀的语法 create table ... like , 可以快速复制一张表,创建其副本。 PostgreSQL 也有类似的语法,而且更加灵活,不过要注意些细节。 先来看看MySQL 语法: create table ... like 原始表T1,结构如下: +----------+------------------+------+-----+---------+----------------+|Field|Type|Null|Key|Default|Extra|+-------

使用PBIS将Linux加入域 - 2015-03-16 06:03:13

使用PBIS将Linux加入域 很多企业已经部署的微软的活动目录,为了方便管理,可以把Linux加入域。网上流传了很多把Linux加入域的方法,感觉比较复杂,并且似乎并没有真正的加入域。只是完成了创建计算账户。使用我提到的方法可以让我这种Linux外行也能很快的将Linux加入Windows活动目录,并且使用域账户登录系统。并且可以给不同的用户或组添加sudo权限,并且不必告知他们root的密码。 PowerBroker Identity Services 的Open Edition可以在这里下载到 ht