在企业应用中,用户的用户名、密码和角色等信息一般存放在RDBMS(关系数据库)中。前面几节我们采用的是InMemoryDaoImpl,即基于内存的存放方式。这节我们将采用RDBMS存储用户信息。

UserDetailsService的接口实现有JdbcDaoImpl和InMemoryDaoImpl。JdbcDaoImpl通过数据库获取用户名、密码和角色信息,它将是接下来的重点内容。

1、简单JdbcDaoImpl配置

默认时, JdbcDaoImpl会采用如下SQL获得用户名、密码、启用状态:

SELECT username, password, enabled From users WHERE username=?

类似地, JdbcDaoImpl会采用如下SQL获得用户的授权信息(角色集合):

SELECT username, authority FROM authorities WHERE username=?

所以, 只要数据库中有这两个表和相应字段, 那么只需这样配置:

  1. <SPAN style="FONT-SIZE: small"><bean id="daoAuthenticationProvider"
  2. class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
  3. <property name="userDetailsService" ref="jdbcDaoImpl" />
  4. ...
  5. </bean>
  6. <bean id="jdbcDaoImpl"
  7. class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
  8. <property name="dataSource">
  9. <ref bean="dataSource" />
  10. </property>
  11. </bean>
  12. </SPAN>
<bean id="daoAuthenticationProvider"
class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="jdbcDaoImpl" />
...
</bean>
<bean id="jdbcDaoImpl"
class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>

在这里,我们只需提供dataSource(数据源)的配置信息,并将dataSource注入到JdbcDaoImpl中。

2Hsqldb使用配置

Hsqldb 是一个优秀的轻量级开源的纯Java SQL 数据库,大家可以从Hsqldb 官方网站(http://hsqldb.org)获取到Hsqldb 的发布包、源代码和文档。

转自他人的简单使用教程:

初用 hsqldb

今天初了下 hsqldb

下载 hsqldb

http://sourceforge.net/project/showfiles.php?group_id=23316

下载 hsqldb_1_8_0_7.zip

解压到 D:/hsqldb

在 D:/hsqldb 目录下创建 runxdb.bat 文件如下:

cd data

java -cp ../lib/hsqldb.jar org.hsqldb.Server -database.0 xdb -dbname.0 xdb

然后双击 runxdb.bat 启动 hsqldb Server

到目录 demo 下运行 runManagerSwing.bat 来创建表

type : HSQL Database Engine Server

url : jdbc:hsqldb:hsql://localhost/xdb

user : SA

建表:

CREATE MEMORY TABLE TEXT(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,NAME VARCHAR);

添加数据:
INSERT INTO TEXT VALUES(1,'chenlb')
INSERT INTO TEXT VALUES(2,'Tenny')

Java 文件

  1. package hsqldb;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7. /**
  8. *
  9. * @author chenlb 2007-4-28
  10. *
  11. */
  12. public class HsqldbFirstSimple {
  13. /**
  14. * @param args
  15. */
  16. public static void main(String[] args) {
  17. // TODO Auto-generated method stub
  18. try {
  19. Class.forName("org.hsqldb.jdbcDriver" );
  20. } catch (Exception e) {
  21. System.out.println("ERROR: failed to load HSQLDB JDBC driver.");
  22. e.printStackTrace();
  23. return;
  24. }
  25. try {
  26. Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb", "sa", "");
  27. Statement stmt = c.createStatement();
  28. ResultSet rs = stmt.executeQuery("select * from text");
  29. while(rs.next()) {
  30. System.out.println(rs.getString(1)+"\t"+rs.getString(2));
  31. }
  32. } catch (SQLException e) {
  33. // TODO Auto-generated catch block
  34. e.printStackTrace();
  35. }
  36. }
  37. }
package hsqldb;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; /**
*
* @author chenlb 2007-4-28
*
*/
public class HsqldbFirstSimple { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub try {
Class.forName("org.hsqldb.jdbcDriver" );
} catch (Exception e) {
System.out.println("ERROR: failed to load HSQLDB JDBC driver.");
e.printStackTrace();
return;
} try {
Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb", "sa", "");
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("select * from text");
while(rs.next()) {
System.out.println(rs.getString(1)+"\t"+rs.getString(2));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

本节中用到的数据库脚本:
CREATE SCHEMA PUBLIC AUTHORIZATION DBA
CREATE MEMORY TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(50) NOT NULL,ENABLED BOOLEAN NOT NULL)
CREATE MEMORY TABLE AUTHORITIES(USERNAME VARCHAR_IGNORECASE(50) NOT NULL,AUTHORITY VARCHAR_IGNORECASE(50) NOT NULL,CONSTRAINT FK_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME))
CREATE USER SA PASSWORD ""
GRANT DBA TO SA
SET WRITE_DELAY 20
SET SCHEMA PUBLIC
INSERT INTO USERS VALUES('javaee','password',TRUE)
INSERT INTO USERS VALUES('qiuzj','password',FALSE)
INSERT INTO USERS VALUES('sam','password',TRUE)
INSERT INTO AUTHORITIES VALUES('javaee','ROLE_SUPERVISOR')
INSERT INTO AUTHORITIES VALUES('sam','ROLE_USER')
INSERT INTO AUTHORITIES VALUES('qiuzj','ROLE_SUPERVISOR')

数据源配置:

  1. <beans>
  2. <bean id="dataSource"
  3. class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  4. <property name="driverClassName">
  5. <value>org.hsqldb.jdbcDriver</value>
  6. </property>
  7. <property name="url">
  8. <value>jdbc:hsqldb:hsql://localhost/</value>
  9. </property>
  10. <property name="username">
  11. <value>sa</value>
  12. </property>
  13. <property name="password">
  14. <value></value>
  15. </property>
  16. </bean>
  17. </beans>
<beans>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="url">
<value>jdbc:hsqldb:hsql://localhost/</value>
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
</beans>

在源代码中,我提供了相应脚本,存放在Acegi5\WebRoot\rdbms目录下。
启动hsqldb数据库只须在rdbms目录下运行server.bat文件,内容为:
      "%JAVA_HOME%/bin/java" -classpath ..\WEB-INF\lib\hsqldb.jar org.hsqldb.Server -database acegidb
      进入hsqldb客户端管理工具请运行manager.bat文件,内容为:
      "%JAVA_HOME%/bin/java" -classpath ..\WEB-INF\lib\hsqldb.jar org.hsqldb.util.DatabaseManager
      实际调试我们可以根据实际情况进行修改。

3、自定义SQL语句
      在开发实际企业应用期间,用户信息的获取方式往往是千差万别的,所以可能不存在users、authorities表和相应名字的属性。考虑到这方面的需求,Acegi的JdbcDaoImpl为我们暴露了usersByUsernameQuery和authoritiesByUsernameQuery属性,它们分别用于自定义SQL语句,获取系统用户和授权信息。
      此时jdbcDaoImpl配置如:

  1. <bean id="jdbcDaoImpl"
  2. class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
  3. <property name="dataSource">
  4. <ref bean="dataSource" />
  5. </property>
  6. <property name="usersByUsernameQuery">
  7. <value>
  8. SELECT username, password, enabled From users WHERE
  9. username=?
  10. </value>
  11. </property>
  12. <property name="authoritiesByUsernameQuery">
  13. <value>
  14. SELECT username, authority FROM authorities WHERE username=?
  15. </value>
  16. </property>
  17. </bean>
<bean id="jdbcDaoImpl"
class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource">
<ref bean="dataSource" />
</property> <property name="usersByUsernameQuery">
<value>
SELECT username, password, enabled From users WHERE
username=?
</value>
</property>
<property name="authoritiesByUsernameQuery">
<value>
SELECT username, authority FROM authorities WHERE username=?
</value>
</property>
</bean>

4、说明
开发环境:
MyEclipse 5.0GA
Eclipse3.2.1
JDK1.5.0_10
tomcat5.5.23
acegi-security-1.0.7
Spring2.0

Jar包:
acegi-security-1.0.7.jar
Spring.jar(2.0.8)
commons-codec.jar
jstl.jar (1.1)
standard.jar
commons-logging.jar(1.0)
hsqldb.jar(1.8.0.10)

菜鸟-手把手教你把Acegi应用到实际项目中(6)的更多相关文章

  1. 菜鸟-手把手教你把Acegi应用到实际项目中(8)-扩展UserDetailsService接口

    一个能为DaoAuthenticationProvider提供存取认证库的的类,它必须要实现UserDetailsService接口: public UserDetails loadUserByUse ...

  2. 菜鸟-手把手教你把Acegi应用到实际项目中(10)-保护业务方法

    前面已经讲过关于保护Web资源的方式,其中包括直接在XML文件中配置和自定义实现FilterInvocationDefinitionSource接口两种方式.在实际企业应用中,保护Web资源显得非常重 ...

  3. 菜鸟-手把手教你把Acegi应用到实际项目中(1.1)

    相信不少朋友们对于学习Acegi的过程是比较痛苦的,而且可能最初一个例子都没能真正运行起来.即使能运行起来,对于里面那么多的配置,更搞不清楚为什么要那么配,多配一个和少配一个究竟有什么区别? 最终头都 ...

  4. 菜鸟-手把手教你把Acegi应用到实际项目中(11)-切换用户

    在某些应用场合中,我们可能需要用到切换用户的功能,从而以另一用户的身份进行相关操作.这一点类似于在Linux系统中,用su命令切换到另一用户进行相关操作.      既然实际应用中有这种场合,那么我们 ...

  5. 菜鸟-手把手教你把Acegi应用到实际项目中(12)-Run-As认证服务

    有这样一些场合,系统用户必须以其他角色身份去操作某些资源.例如,用户A要访问资源B,而用户A拥有的角色为AUTH_USER,资源B访问的角色必须为AUTH_RUN_AS_DATE,那么此时就必须使用户 ...

  6. 菜鸟-手把手教你把Acegi应用到实际项目中(7)-缓存用户信息

    首先讲讲EhCache.在默认情况下,即在用户未提供自身配置文件ehcache.xml或ehcache-failsafe.xml时,EhCache会依据其自身Jar存档包含的ehcache-fails ...

  7. 菜鸟-手把手教你把Acegi应用到实际项目中(5)

    在实际企业应用中,用户密码一般都会进行加密处理,这样才能使企业应用更加安全.既然密码的加密如此之重要,那么Acegi(Spring Security)作为成熟的安全框架,当然也我们提供了相应的处理方式 ...

  8. 菜鸟-手把手教你把Acegi应用到实际项目中(4)

    今天就讲个ConcurrentSessionFilter. 在Acegi 1.x版本中,控制并发HttpSession和Remember-Me认证服务不能够同时启用,它们之间存在冲突问题,这是该版本的 ...

  9. 菜鸟-手把手教你把Acegi应用到实际项目中(1.2)

    7) daoAuthenticationProvider 进行简单的基于数据库的身份验证.DaoAuthenticationProvider获取数据库中的账号密码并进行匹配,若成功则在通过用户身份的同 ...

随机推荐

  1. [mysql] ERROR 1862 (HY000): Your password has expired. To log in you must change it using a client that supports expired passwords.

    今天安装mysql遇到这样一个问题: ERROR 1862 (HY000): Your password has expired. To log in you must change it using ...

  2. [java] JVM监控与调优

    原文出处:http://www.cnblogs.com/zhguang/p/java-jvm-gc.html   光说不练假把式,学习Java GC机制的目的是为了实用,也就是为了在JVM出现问题时分 ...

  3. ios外包公司——技术分享:IOS开发教程

        iOS入门培训,适合已经有C/C++/Java/C#基础的人学习.   本大仙主讲,总共4讲(第4讲尚在制作中),这仅仅是iOS开发的入门而已.学完本教程,应该已经足够你自学并开发app了. ...

  4. jQuery制作视频网站的展示效果

    效果:如图所示,用户可以单击左上角的左右箭头,来控制视频展示的左右滚动. 当单击向右箭头时下面的展示视频会向左滚动隐藏,同时新的视频展示会以滚动方式显示出来.向左同理. css: ;; word-br ...

  5. Spring实战5:基于Spring构建Web应用

    主要内容 将web请求映射到Spring控制器 绑定form参数 验证表单提交的参数 对于很多Java程序员来说,他们的主要工作就是开发Web应用,如果你也在做这样的工作,那么你一定会了解到构建这类系 ...

  6. Python IDE Tools

    PyCharmhttps://www.jetbrains.com/pycharm/download/ Sublimehttp://www.sublimetext.com/

  7. Expecting "jsp:param" standard action with "name" and "value" attributes错误

    错误信息如下: Servlet.service() for servlet [jsp] in context with path [/20161017] threw exception [/tag/s ...

  8. IO操作 第一篇 学习(转载)

    问题8:如何使用通配符搜索指定目录内的所有文件: 解决方案: 使用DirectoryInfo.GetFiles方法的重载版本,它可以接受一个过滤表达式,返回FileInfo数组,另外它的参数还可以指定 ...

  9. 我的Android最佳实践之—— Android启动画面的实现方法

    本文实例讲述了Android启动画面的实现方法.分享给大家供大家参考.具体分析如下: 在应用程序中经常用到启动画面,会启动一个后台线程为主程序的运行准备资源.Android要实现启动画面可以这样做: ...

  10. (WPF) 再议binding:点击User Control时,User Control变换颜色或做其他的处理。

    Binding 是前台UI(显示层)和后台代码(数据层)的桥梁.理论上当后台的数据变动时,显示的数据或样式应该随之而变.这些是动态的. 对于Binding的设置可以在前台Xaml,也可以在后台Code ...