原文:JDBCRealm
in Glassfish
作者:Shing Wai Chan
译者:Cheng Fang
JDBC realm 在近几个月来颇受瞩目。这篇网志总结了 JDBC realm 在GlassFish 实施中的演变,并解释其最新的实施运作。我要感谢 Jean-Baptiste 和 Richter 对此所作的贡献和评论。开源社区成员的参与也很有帮助。我欢迎大家的反馈和参与, 帮助我们更好地实现这一性能。
GlassFish 一直都支持 realm 插件。以下这篇文章描述了如何在 Sun Java System Application Server EE 8.0 中实现 Custom Realm:Authentication Using Custom Realms in Sun Java System Application Server。S1AS 7.x 也里有一个JDBC realm 的示例。Jean-Baptiste 正式提出要求这一性能, 并为 Glassfish 提供了一个以明文的方式实现的 JDBCRealm。Richter 也提供了另一个实 施方案,因为当时GlassFish 中的 JDBCRealm 与Tomcat 不兼容。
GlassFish 中最新的 JDBCRealm 是基于Jean-Baptiste 的实施,并包含了以下一些改动:
- 增加 Message Digest 配置
- 增加对 Digest 的 encoding 配置
- 增加 charset 配置
- 增加 realm 中数据库用户和密码配置
- 解决为 EJB 获取连接的问题
在 GlassFish 中设计、实施 JDBCRealm 的过程中, 我们作出了以下一些决定:
- 应该不应该支持明文密码? 我们决定支持明文密码,但不作为缺省存贮机制。在正常情况下, 密码不应该被明文地存放。
- 是不是应该与 Tomcat 和 JBoss 兼容? 我们决定在实施中尽量做到兼容, 但不作为一个要求。
我们想听听你对这两个方面的意见。
GlassFish JDBCRealm
下表概括了 GlassFish JDBCRealm 中可配置的属性:
| 属性 | 是否必须 | 缺省 | 备注 |
|---|---|---|---|
datasource-jndi |
是 |
||
user-table |
是 |
||
user-name-column |
是 |
和 Tomcat 一样, 我们假设 user-table 表和 group-table 表有这一栏 | |
password-column |
是 |
||
group-table |
是 |
||
group-name-column |
是 |
||
jaas-context |
是 |
jdbcRealm | |
db-user |
否 |
沿用连接池配置 | 如果连接池没有用户名或密码, 在这里定义db-user和db-password。这能够让我们指定一个安 全的资源,realm 可以通过用户名和密码来访问。 |
db-password |
|||
digest-algorithm |
否 |
MD5 | 支持 JDK 中所有算法, 和 "none" |
encoding |
否 |
如果有 digest-algorithm, 就用 Hex。如果没有定义 digest, 则不用 encoding。 |
Hex, Base64, 不指定(没有 encoding) |
charset |
否 |
针对 digest 的 charset |
GlassFish 中的一个安全性能就是,你可以在 JDBCRealm 中, 而不是在连接池中,指定用户名和密码。这样, 其它应用就无法查找 datasource,得到连接来浏览用户名和密码表。
怎么在JavaEE 应用中使用JDBCRealm ?
- 为 JDBCRealm 创建数据库表。
例如, 如果您使用 Derby, 您会创建如以下示例的数据库表:create table usertable(userid varchar(10) not null, password varchar(32) not null, primary key(userid));
create table grouptable(userid varchar(10) not null, groupid varchar(20) not null, primary key(userid));
alter table grouptable add constraint FK_USERID foreign key(userid) references usertable(userid); - 通过Admin 控制台创建 JDBCRealm。
例如, 你可以创建一个有以下属性的 JDBCRealm:Property NameProperty Valuedatasource-jndijdbc/securityuser-tableusertableuser-name-columnuseridpassword-columnpasswordgroup-tablegrouptablegroup-name-columngroupidjaas-contextjdbcRealmjdbc/security是一个可以访问以上表格的 datasource。
- 指定 JDBCRealm 是当前应用使用的 realm。这在配置描述器里指明:
sun-application.xml(对于 EAR) 或,web.xml(对于 WAR) 或sun-ejb-jar.xml(对于 EJB Jar) 。 - 确认
sun-*.xml 文件里有<security-role-mapping>。 例如,
<security-role-mapping>
<role-name>Employee</role-name>
<principal-name>Calvin</principal-name>
</security-role-mapping> - 在数据库中创建一名用户。没有为 JDBCRealm 创造用户的管理工具。以下是一个用来创建 JDBCRealm 用户程序例子:
...
可以在这 里找到这个例子。当运行这一程序时, 要确认 JDBC 驱动在 CLASSPATH 里,例如,
private static final String userSql = "insert into usertable values(?, ?)";
private static final String groupSql = "insert into grouptable values(?, ?)";
private static String hashPassword(String password) throws Exception {
...
//compute digest
...
//encode the bytes
...
}
public static void main(String args[]) throws Exception {
...
Class.forName(driver);
String hPassword = hashPassword(password);
Connection conn = DriverManager.getConnection(
jdbcUrl, dbUser, dbPassword);
PreparedStatement userStmt = conn.prepareStatement(userSql);
userStmt.setString(1, user); userStmt.setString(2, hPassword);
userStmt.executeUpdate();
userStmt.close();
...
}$GLASSFISH_HOME/javadb/lib/derbyclient.jar
关于迁移
从 Tomcat 或者 JBoss 迁移到 GlassFish 时,应考虑到以下一些不同的地方:
- 在 Tomcat 和 JBoss, 没有缺省值。这对应于 GlassFish 中的 digest-algorithm="none"。
- 在GlassFish 和Tomcat 中, 如果有 digest 被定义,那么 encoding 缺省值就是 Hex。在 JBoss 中, 如果有 digest 被定义,那么 encoding 缺省值就是 Base64。
Posted by 请教 on December 04, 2006 at 02:46 AM PST #
very cool
Posted by BATTERY on November 28, 2008 at 04:29 AM PST #
你好,网上看见您的文章,感觉很好。能否也将详细步骤发给我下。
最好包括glashfish的详细操作。我将万分感激!!谢谢
mrtinkles_lele@hotmail.com
Posted by 58.35.199.30 on June 14, 2009 at 06:36 PM PDT #
really interesting sir, thanks
Posted by tiffany & co Pendant on November 12, 2009 at 11:19 PM PST #