WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例

1. 简介

WebSphere Application Server提供了非常成熟强大的J2EE安全认证机制。WebSphere Application Server启动安全模式,有3种用户注册表(安全认证的数据源):

1) 本地操作系统(Local OS)

2) 轻量级目录访问协议(LDAP)

3) 定制用户注册表(Custom User Registry)

其中方式一和方式二快速方便,无需建立专门的用户数据库。但是,更多时候,客户拥有独立的用户验证数据库存储用户安全信息。方式三使得WebSphere Application Server可以和任意类型数据源进行整合,比如数据库,文件系统,甚至是网络认证服务器。

2. 本文示例环境

WebSphere Application Server v6.0 on Redhat AS3.0
IBM DB2 Universal v8.1
Rational Software Architect 6.0

本文通过一个实例DemoCustomUserRegistry工程来阐述如何定制用户注册表将用户数据库与WebSphere Application Server安全认证整合,作为WebSphere Application Server后台验证数据。

3. 定制用户注册表概念

定制用户注册表是一个定制实现的用户注册表,它实现了WebSphere Application Server提供UserRegistry Java接口。一个定制用户注册表可以支持任意类型的用户数据源,包括关系型数据库,文件系统等等,因此,定制用户注册表在整合已有用户数据源方面非常适用。UserRegistry接口规定了是用来定义WebSphere Application Server对密码或是安全证书进行验证的一系列方法,一个定制用户注册表必须实现UserRegistry接口中的全部方法。

4. UserRegistry接口概述

UserRegistry接口包括的用户信息:

  • 用户安全名字(User Security Name):用于验证的用户名字,就如本地操作系统验证方式的用户名。
  • 用户唯一ID(User Unique ID):每个用户对应的唯一ID。
  • 用户显示名字(User Display Name):可选项,用于显示该用户的名字,比如在欢迎界面,相当于本地操作系统验证方式下的该用户的全名。
  • 组安全名字(Group Security Name):用于验证的组的名字,就如本地操作系统的用户。
  • 组唯一ID(Group Unique ID):每个组对应的唯一ID。
  • 组显示名字(Group Display ID):可选项,用于显示该组的名字,比如在欢迎界面,相当于本地操作系统验证方式下的该组的全名。

UserRegistry接口必须实现的方法:

  • initialize
  • checkPassword
  • mapCertificate
  • getRealm
  • getUsers
  • getUserDisplayName
  • getUniqueUserId
  • getUserSecurityName
  • isValidUser
  • getGroups
  • getGroupDisplayName
  • getUniqueGroupId
  • getUniqueGroupIds
  • getGroupSecurityName
  • isValidGroup
  • getGroupsForUser
  • getUsersForGroup
  • createCredential

5. 实现UserRegistry接口

必须实现UserRegistry接口定义的所有方法(createCredential方法例外)。下面详细介绍与整合密切相关的两个方法initialize 和checkPassword,并给出DemoCustomRegistry中的实现代码。

initialize方法

初始化方法,可在该函数里读取一些在WebSphere Application Server为该用户注册表所作一些属性配置。DemoCustomUserRegistry将从WebSphere Application Server配置中读取db2url,db2user,db2password属性。具体配置方法将在"配置定制用户注册表"部分详述。

public void initialize(Properties props) throws CustomRegistryException,RemoteException {
        	try {
                  if (props != null) {
                      DB2URL = props.getProperty("db2url");
                      DB2USER = props.getProperty("db2user");
                      DB2PASSWORD = props.getProperty("db2password");
                  }
              } catch(Exception ex) {
                 throw new CustomRegistryException(ex.getMessage(),ex);
              }
              if (DB2URL == null || DB2USER == null || DB2PASSWORD == null ) {
                 throw new CustomRegistryException("users/groups information missing");
              }
              configOK = true;
    }
   }



checkPassword方法

checkPassword方法用于验证该用户名以及对应的密码是否合法。该函数是整合用户数据源的关键。DemoUserCustomRegistry从DB2数据库的EMPLOYEE表里查询对应的用户信息,如果验证成功,返回该用户名,验证失败,则抛出验证失败异常。


public String checkPassword(String userSecurityName, String passwd)
            throws PasswordCheckFailedException, CustomRegistryException,
            RemoteException {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        boolean validUser = false;
        try{
            Class.forName(DB2DRIVER).newInstance();
			conn = DriverManager.getConnection(DB2URL,DB2USER,DB2PASSWORD);
			if(null != conn){
			    ps = conn.prepareStatement(AUTHSQL);
	            ps.setString(1,userSecurityName);
	            ps.setString(2,passwd);
	            rs = ps.executeQuery();
	            if(rs.next())
	                validUser = true;
			}
        }catch(Exception e){
            System.out.println("Andrew: DB Exception!"+e.toString());//$NON-NLS-1$
        }finally{
            if(null != rs){
                try {
                    rs.close();
                } catch (SQLException e) {
                }
            }
            if(null != ps){
                try {
                    ps.close();
                } catch (SQLException e){
                   
                }
            }
            if(null != conn){
                try {
                    conn.close();
                } catch (SQLException e) {
                }
            }
        }
        if (validUser == false) {
           throw new PasswordCheckFailedException("Password check failed for user: " 
		   + userSecurityName);
        } 
        return userSecurityName;
}


其他方法

  • mapCertificate(X509Certificate[]) :mapCertificate方法从浏览器中X.509安全证书链映射成为用户名。
  • getRealm:返回注册表所在域,比如在OS/400或是AIX上,应该返回系统的主机名,其他情况可以返回默认值"customRealm"。
  • getUserDisplayName:根据安全用户名(Security User Name),得到显示用户名(Display User Name),一般情况返回同样的名字即可。
  • getUniqueUserId:根据安全用户名,得到该用户的唯一ID。
  • getUserSecurityName:根据用户的唯一ID得到用户的安全用户名。
  • isValidUser:该用户名是否合法用户。
  • getGroups:根据匹配模式,得到符合该模式的组列表。
  • getGroupDisplayName:根据组安全名字,得到组显示名字。
  • getUniqueGroupId:根据组的安全名字,得到组的唯一ID。
  • getUniqueGroupIds:得到包含该用户的所有组唯一ID列表。
  • getGroupSecurityName:根据组的唯一ID得到组的安全名字。
  • isValidGroup:是否合法组。
  • getGroupsForUser:得到包含该用户的所有组的安全名字列表。
  • getUsersForGroup:得到该组的所有用户列表。
  • createCredential:该接口在WebSphere Application Server v6.0中有内部实现,定制用户注册表时只需返回null即可。

6. 配置定制用户注册表

1) 新建Java工程 DemoCUR, 并在项目中新建package,取名为com.test,将本文例子代码中的DemoCustomUserRegistry.java导入项目工程,并在工程项目的"Java Build Path"中添加sas.jar 和 wssec.jar。


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第1张图片

2) 拷贝com/test/DemoCustomUserRegistry.class的目录结构至WebSphere Application Server v6.0的扩展库路径下,一般为(/opt/IBM/WebSphere/lib/ext)。


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第2张图片

3) 登陆WebSphere Application Server控制台。在浏览器中输入http://wasip:9060/admin。在左导航面板中,单击"Security",单击"Global Security"。


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第3张图片

4) 选中"Enable global security"复选框,"Active User Registry"中选择"Custom User Registry"。



5) 单击"OK"。

6) 单击右导航栏中的"User Registry"下的"Custom"。


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第4张图片

7) 在"Server user ID"中输入用于登陆控制台的帐号,在"Server user password"中输入该帐号对应的密码,在"Custom registry class name"中输入"com.test.DemoCustomUserRegistry"。


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第5张图片

8) 点击"Apply"。

9) 点击"Additional Properties"下的"Custom properties"。


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第6张图片

10) 点击"New"。 在"Name"中输入"db2url",在"Value"中输入"jdbc:db2://dbip:50000/dbname",


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第7张图片

11) 重复步骤10,分别建立变量"db2user","db2password",对应的值分别为用户数据库的db验证用户名和密码。

12) 点击"Custom User Registry"返回到定制用户注册表配置页面


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第8张图片


13) 拷贝JDBC驱动程序(db2jcc.jar, db2jcc_license_cisuz.jar, db2jcc_license_cu.jar)至WebSphere Application Server v6.0的库路径下(如果已经存在则可省略这步)。

14) 点击"OK"

15) 保存配置。

16) 重新启动WebSphere Application Server 6.0。 至此,WebSphere Application Server 6.0的安全认证已经采用用户数据库。

7. 安装带有安全验证配置的Web Application

1) 登陆控制台, http://wasip:9060/admin。

2) 输入上部分配置的用户名密码。

3) 安装Login.ear。

4) 启动FormLoginSample。

5) 在浏览器中输入http://wasip:9080/TestLoginWeb/secure/welcome.jsp。

WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第9张图片

6) 输入数据库中存在的正确的用户名和密码


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第10张图片

7) 单击Login,则页面跳转到登陆成功页面


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第11张图片

8) 新开浏览器窗口,并重复上述步骤5-6,输入错误用户名密码,单击Login,则页面跳转到登陆失败页面。


WebSphere Application Server 6.0安全认证与已有系统的用户数据库整合实例_第12张图片

8. 注意事项

避免实现定制用户注册表的过程中使用其它 WebSphere Application Server 组件来初始化定制注册表。例如,在定制注册表的初始化期间,使用基于WebSphere Application Server数据库连接池来连接至基于数据库的用户注册表。或在初始化期间,使用已部署的企业 Bean。这会导致失败,因为在初始化安全性之前不会初始化其它组件(如容器),因而这些组件在注册表初始化期间不可用。所以定制用户注册表实现不应依赖于其它 WebSphere Application Server 组件。

9. 小结

WebSphere Application Server 支持的定制用户注册表方式非常适合整合已有的用户认证数据库。通过本文,读者应该不难去整合除IBM DB2之外的用户数据库,文件系统,甚至是网络认证服务器。

10. 下载

CUR_CODES.zip :包含DemoCustomUserRegistry.java, Login.ear两个工程文件源代码。

你可能感兴趣的:(数据库,server,db2,user,application,websphere)