使用 UDDI V3 API 构建安全的 UDDI 应用

本文主要介绍了 IBM UDDI 的安全选项配置以及对应的 UDDI V3 API 的使用。深入剖析了 IBM UDDI 中的 UDDI Publishers, APIs 等高级选项的配置。在文章中,作者给出了使用 UDDI V3 API 与用户个性化安全选项配置协同工作的代码片段。对于不同厂商的 UDDI 产品对 UDDI V3 API 的不同的需求,本文也有涉及。在文章的下载部分,读者可以下载完整的代码来学习 UDDI V3 API 的使用。

介绍

IBM UDDI 是作为 WebSphere 应用服务器的应用程序来发布的。用户可以按照 WebSphere 应用服务器信息中心的步骤(http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/twsu_default_install2.html)来安装一个 UDDI 服务器。IBM UDDI 可以利用 WebSphere 应用服务器的安全机制来构建自己的安全框架。IBM UDDI 也可以使用 authentication token 来进行安全的查询,发布等操作。

  • 平台安全机制
    • 授权

      授权决定了哪一个用户可以访问何种服务。WebSphere 应用服务器对用户,或者一组用户授予对应的用户角色。预定义的常用用户角色如图 1 所示。

      • GUI_Publish_User/GUI_Inquiry_User 是从网页界面来访问 UDDI 的用户角色 , 例如界面 http://localhost:9080/uddigui。
      • SOAP_Publish_User/SOAP_Inquiry_User 是出于兼容性考虑为使用 UDDI V1,UDDI V2 API 的用户保留的用户角色。
      • EJB_Inquiry_Role/EJB_Publish_Role 是使用 EJB 访问的用户角色。
      • V3SOAP_Inquiry_User_Role/V3SOAP_Publish_User_Role/V3SOAP_CustodyTransfer_User_Role/V3SOAP_Security_User_Role 是使用 UDDI V3 API 的用户角色。
图 1. UDDI 用户与用户角色对应关系
    • 数据保密

数据保密保证了在网络传输层的数据安全性。WebSphere 应用服务器的数据安全性可以是“无“(使用 HTTP 作为传输协议)或者“保密”(需要使用安全套接字协议 SSL 使用 HTTPS 作为传输协议)。通常的获得数据保密性的方法是使用 SSL 协议。SSL 协议为 WebSphere 应用服务器上的客户端和服务器端的安全连接提供了传输层的安全性。SSL 通过对数据加密避免了在数据传输时泄露敏感信息。数字签名则保证了数据传输时数据不会被篡改。客户端和服务器端的认证保证了用户同正确的用户和机器在进行交互。用户需要对 UDDI 发布 API 设置用户名,密码;对 UDDI 查询 API 则不需要设置用户名,密码。

UDDI_Publication_PortType publishPort; 
//Get UDDI_Publication_PortType from UDDI_Service
((javax.xml.rpc.Stub) publishPort)
._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, user); 
((javax.xml.rpc.Stub) publishPort)
._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, password); 
  • UDDI 安全机制

UDDI 标准建议使用在 UDDI API 上使用 authentication token 来保证安全性。下文是 UDDI 第三版规范中关于 authentication token 的摘录:

The security API includes the following API calls: • discard_authToken: Used to inform a node that a previously obtained authentication token is no longer required and should be considered invalid if used after this message is received. • get_authToken: Used to request an authentication token in the form of an authInfo element from a UDDI node. An authInfo element MAY be required when using the API calls defined in Section 5.1 Inquiry API Set, Section 5.2 Publication API Set, Section 5.4 Custody and Ownership Transfer API Set, and Section 5.5 Subscription API Set.

当用户需要做 UDDI 查询 / 发布操作时,用户可以在 API 上设置从 Get_authToken 获得的 authentication token。当然用户需先对 Get_authToken 设置用户 / 密码,然后才能获取 authentication token。

org.uddi.v3.schema.api.Get_authToken getAuthToken = new Get_authToken();
getAuthToken.setUserID(username); 
getAuthToken.setCred(password); 
AuthToken authToken =(UDDI_Security_PortType)securityPort.get_authToken(getAuthToken);

对于每一个查询 / 发布 API,它含有如图 2 所示的 authInfo 参数。

图 2. save_business API

save_business 调用被用来存储或者更新一个 businessEntity 上的信息。authInfo 这个可选的参数是一个包含 authentication token 的元素。authentication token 可以通过 get_authToken API 或者 UDDI 规范之外的方法获得。当 UDDI 服务器有多个发布者或者需要限制哪一个发布者可以发布信息时,就需要在 API 上设置 authInfo。用户可以用如下代码来保证 save_business API 的安全:

Save_business saveBusiness = new Save_business();
saveBusiness.setAuthInfo(authToken.getAuthInfo());

当 UDDI 服务器接收到来自客户端的一个 Save_business 请求后,它首先要判断 authentication token 里包含的用户名 / 密码信息是不是同 UDDI 服务器上注册用户信息一致,如果一致,则成功保存 businessEntity。

回页首

访问开启平台安全的 UDDI

如果用户想连接开启平台安全的 UDDI,用户需要在 WebSphere Application Server 控制台下开启安全。在 Security>Secure administration, applications, and infrastructure 下确保 administrative security 和 application security 已被开启。用户可以参照 WebSphere Application Server 信息中心来获得更多的信息。

图 3. WebSphere Application Server 安全设置

当 UDDI 的平台安全打开后,用户可以在 Enterprise Applications>UDDIRegistry.UDDINode.server1>Security role to user/group mapping 下察看默认的安全设置。在默认设置下,V3SOAP_Inquiry_User_Role 被授权给“Everyone”,说明任何用户都可以从 UDDI 中查寻内容;V3SOAP_Publish_User_Role 被授权给“All authenticated”,说明只有被授权的用户才能向 UDDI 中发布内容。详细信息请参见图1。

如果用户想向打开平台安全的 UDDI 发布或查询内容时,可以通过以下方式:

  1. 获取 ServiceFactory UDDI_Service
    ServiceFactory factory = ServiceFactory.newInstance();
    UDDI_ServiceuddiService =(UDDI_Service)factory.loadService(UDDI_Service.class);
    
  2. 获取 UDDI_Publication_PortTypeUDDI_Inquiry_PortType
    UDDI_Publication_PortType publishPort = uddiService.getUDDI_Publication_Port();
    UDDI_Inquiry_PortType inquiryPort = uddiService.getUDDI_Inquiry_Port();
    
  3. 设置 publish URL, inquiry URL 和安全信息 (username, password, trustStore, trustStore password, keyStore and keyStore password)。
    (((Stub) publishPort)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, publishURL);
    ((Stub) publishPort)._setProperty(Stub.USERNAME_PROPERTY, userName);
    ((Stub) publishPort)._setProperty(Stub.PASSWORD_PROPERTY, password);
    
    ((Stub)inquiryPort)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, inquiryURL);
    ((Stub) inquiryPort)._setProperty(Stub.USERNAME_PROPERTY, userName);
    ((Stub) inquiryPort)._setProperty(Stub.PASSWORD_PROPERTY, password);
    
    System.setProperty("javax.net.ssl.trustStore", trustStore);
    System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
    System.setProperty("javax.net.ssl.keyStore", keyStore);
    System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword); 
    
  4. 向 UDDI 发布内容。
     Name businessName[] = new Name[1];
    businessName[0] = new Name();
    businessName[0].set_value("BusinessEntity");
    BusinessEntity newBusinesses[] = new BusinessEntity[1];
    newBusinesses[0] = new BusinessEntity();
    newBusinesses[0].setName(businessName);
    Save_business saveBusiness = new Save_business();
    saveBusiness.setBusinessEntity(newBusinesses);
    BusinessDetail businessDetail = publishPort.save_business(saveBusiness);
    URI businessKey = businessDetail.getBusinessEntity(0).getBusinessKey();
    if (businessKey == null) {
    System.out.println("Publish failed.");
    }else{
    System.out.println("Publish succeeded.");
    } 
    
  5. 从 UDDI 中获取内容。
     businessName[0] = new Name();
    businessName[0].set_value("BusinessEntity");
    Find_business findBusiness = new Find_business();
    findBusiness.setName(businessName);
    BusinessList businessList = inquiryPort.find_business(findBusiness);
    BusinessInfos businessInfos = businessList.getBusinessInfos();
    if (businessInfos == null || businessInfos.getBusinessInfo().length == 0) {
    System.out.println("Inquiry failed.");
    }else{
    System.out.println("Inquiry succeeded.");
    } 
    

    注意 :

  6. 关于 V3SOAP_Inquiry_User_Role 的设置 :
    1. 如果“EveryOne”和“All authenticated”都没有被选中会出现错误“(403) Forbidden”。
    2. 如果“EveryOne”被选中,所有的用户都可以从 UDDI 中查寻内容,这时并不需要向 inquiry port 设置用户名和密码。
    3. 如果“All authenticated”被选中,只有被授权的用户才有权限从 UDDI 中查寻内容,这时必须向 inquiry port 设置用户名和密码。如果使用非授权的用户查询会出现错误“(401) Unauthorized”。 
  7. 关于 V3SOAP_Publish_User_Role 的设置 :
    1. 如果“EveryOne”和“All authenticated”都没有被选中 , 错误“(403) Forbidden”会出现。
    2. 如果“EveryOne”被选中会出现 UDDI 错误 10120。
    3. 如果“All authenticated”被选中,只有被授权的用户才有权限向 UDDI 中发布内容,这时必须向 publish port 设置用户名和密码。如果使用非授权的用户发布会出现错误“(401)。
回页首

访问开启 UDDI 安全的 UDDI

UDDI 使用 authentication token 来限制用户的查询和发布操作,以 IBM 的 UDDI 为例,有三个配置选项和 authentication token 有关,他们分别是:

  • Use authInfo credentials if provided
  • Authentication token expiry period
  • Automatically register UDDI publishers

如图 4 所示,这些配置选项可以在 WAS 控制台 WAS console>UDDI Nodes 中找到,图 4 是默认配置,表明采用 authentication token 中的信息来进行 UDDI 操作,同时 authentication token 的过期时间为 30 分钟。

图 4. UDDI 安全配置选项

在这样的安全配置下 , 用户可以采用如下的方式在 UDDI 中查询和发布内容:

  1. 获取 ServiceFactory UDDI_Service
    ServiceFactory factory = ServiceFactory.newInstance();
    UDDI_ServiceuddiService =(UDDI_Service)factory.loadService(UDDI_Service.class);
    
  2. 获取 UDDI Publication, Inquiry, Security PortType
    UDDI_Publication_PortType publishPort = uddiService.getUDDI_Publication_Port();
    UDDI_Inquiry_PortType inquiryPort = uddiService.getUDDI_Inquiry_Port();
    UDDI_Security_PortType securityPort = uddiService.getUDDI_Security_Port();
    
  3. 设置 publish URL, inquiry URL 和 security URL。
    ((Stub) publishPort)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, publishURL);
    ((Stub)inquiryPort)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, inquiryURL);
    ((Stub) securityPort)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, securityURL); 
    
  4. 获取 authentication token。
    Get_authToken getAuthToken = new Get_authToken();
    getAuthToken.setUserID(userName);
    getAuthToken.setCred(password);
    AuthToken authToken = null;
    authToken = securityPort.get_authToken(getAuthToken); 
    
  5. 使用 authenticate token 往 UDDI 中发布内容。
    Name businessName[] = new Name[1];
    businessName[0] = new Name();
    businessName[0].set_value("BusinessEntity");
    BusinessEntity newBusinesses[] = new BusinessEntity[1];
    newBusinesses[0] = new BusinessEntity();
    newBusinesses[0].setName(businessName);
    Save_business saveBusiness = new Save_business();
    saveBusiness.setBusinessEntity(newBusinesses);
    saveBusiness.setAuthInfo(authToken.getAuthInfo());
    BusinessDetail businessDetail = publishPort.save_business(saveBusiness);
    URI businessKey = businessDetail.getBusinessEntity(0).getBusinessKey();
    if (businessKey == null) {
    System.out.println("Publish failed.");
    }else{
    System.out.println("Publish succeeded.");
    } 
    
  6. 使用 authenticate token 从 UDDI 中获取内容。
     businessName[0] = new Name();
    businessName[0].set_value("BusinessEntity");
    Find_business findBusiness = new Find_business();
    findBusiness.setName(businessName);
    findBusiness.setAuthInfo(authToken.getAuthInfo());
    BusinessList businessList = inquiryPort.find_business(findBusiness);
    BusinessInfos businessInfos = businessList.getBusinessInfos();
    if (businessInfos == null || businessInfos.getBusinessInfo().length == 0) {
    System.out.println("Inquiry failed.");
    }else{
    System.out.println("Inquiry succeeded.");
    } 
    

其中获取 authentication token 的方法可以参考上述代码中的第四步,使用 authentication token 只需要在 Find_xxx 和 Save_xxx API 中设置相应的属性,可以参考第 5 步和第 6 步。如果使用 authentication token 访问 UDDI,用户可以对 UDDI 中所有的内容进行查询操作,但是 update/delete 操作只能作用于该用户自己创建的内容。

用户信息是否正确是获取 authentication token 的关键,IBM UDDI 使用下面列出的三处用户信息,并结合上述的配置选项来判断是否给用户提供合法的 authentication token。

  • Get_authToken API 中设置的用户信息
  • UDDI publisher 列表
  • UDDI 默认用户

如果用户同时选择“use authInfo credentials if provided”和 “automatically register UDDI publishers”, 表示使用 authentication token 中的信息,而且如果 authentication token 中包含的用户信息不在 UDDI 的 publisher 列表里面,系统会自动创建一个相应的 UDDI publisher。所以在这种情况下,Get_authToken 操作都会返回一个合法的包含指定用户信息的 authentication token。

如果用户只选择了“use authInfo credentials if provided”, 表示只使用 authentication token 中的信息,而不自动为用户创建 UDDI publisher,所以,只有当 authentication token 中包含的用户信息在 UDDI publisher 列表里面时,才能返回正确的 authentication token。否则返回 10150 错误。

如果用户只选择了“automatically register UDDI publishers”或者两个都不选,表示不使用 authentication token 中所包含的用户信息,UDDI 将使用默认用户来创建 authentication token。所以,不管用户在 Get_authToken API 中设置的是什么值,系统都会返回一个包含默认用户信息的 authentication token。

回页首

访问同时开启 UDDI 安全和平台安全的 UDDI

如果用户在使用 IBM UDDI 的时候,同时打开平台安全和 UDDI 安全 , 那么需要按照下面的方式设置平台安全的信息 (inquiry/publish port 中的 username 和 password 以及 SSL 属性 ):

((Stub) publishPort)._setProperty(Stub.USERNAME_PROPERTY, userName);
((Stub) publishPort)._setProperty(Stub.PASSWORD_PROPERTY, password);
((Stub) inquiryPort)._setProperty(Stub.USERNAME_PROPERTY, userName);
((Stub) inquiryPort)._setProperty(Stub.PASSWORD_PROPERTY, password);
((Stub) securityPort)._setProperty(Stub.USERNAME_PROPERTY, userName);
((Stub) securityPort)._setProperty(Stub.PASSWORD_PROPERTY, password);
System.setProperty("javax.net.ssl.trustStore", trustStore);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
System.setProperty("javax.net.ssl.keyStore", keyStore);
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);

将 authentication token 信息设置到 Save_xxx 和 Find_xxx API 中 :

saveBusiness.setAuthInfo(authToken.getAuthInfo());
findBusiness.setAuthInfo(authToken.getAuthInfo());

注意 :

如果用户不是一个注册的 UDDI publisher,这时需要选择“automatically register UDDI publishers”才能向 UDDI 中发布内容,否则返回 10150 错误。

回页首

访问未开启安全的 UDDI

当 UDDI 没有打开安全,用户可以通过以下方式向 UDDI 发布或查询内容:

  1. 获取 ServiceFactory UDDI_Service
    ServiceFactory factory = ServiceFactory.newInstance();
    UDDI_ServiceuddiService =(UDDI_Service)factory.loadService(UDDI_Service.class);
    
  2. 获取 UDDI_Publication_PortTypeUDDI_Inquiry_PortType
    UDDI_Publication_PortType publishPort = uddiService.getUDDI_Publication_Port();
    UDDI_Inquiry_PortType inquiryPort = uddiService.getUDDI_Inquiry_Port();
    
  3. 设置 publish URL 和 inquiry URL。
    ((Stub) publishPort)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, publishURL);
    ((Stub) inquiryPort)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, inquiryURL); 
    
  4. 向 UDDI 中发布内容 .
    Name businessName[] = new Name[1];
    businessName[0] = new Name();
    businessName[0].set_value("BusinessEntity");
    BusinessEntity newBusinesses[] = new BusinessEntity[1];
    newBusinesses[0] = new BusinessEntity();
    newBusinesses[0].setName(businessName);
    Save_business saveBusiness = new Save_business();
    saveBusiness.setBusinessEntity(newBusinesses);
    BusinessDetail businessDetail = publishPort.save_business(saveBusiness);
    URI businessKey = businessDetail.getBusinessEntity(0).getBusinessKey();
    if (businessKey == null) {
    System.out.println("Publish failed.");
    }else{
    System.out.println("Publish succeeded.");
    } 
    
  5. 从 UDDI 中查寻内容 .
    businessName[0] = new Name();
    businessName[0].set_value("BusinessEntity");
    Find_business findBusiness = new Find_business();
    findBusiness.setName(businessName);
    BusinessList businessList = inquiryPort.find_business(findBusiness);
    BusinessInfos businessInfos = businessList.getBusinessInfos();
    if (businessInfos == null || businessInfos.getBusinessInfo().length == 0) {
    System.out.println("Inquiry failed.");
    }else{
    System.out.println("Inquiry succeeded.");
    } 
    

    注意 : UDDI publish API 会使用默认的用户作为 UDDI entity owner ,默认用户可以在 WebSphere application server 控制台中的 UDDI>UDDI nodes>UDDI Node ID>Default user name 下设置。

回页首

IBM vs 其它 UDDI

总的来说,当用户需要连接其它厂商的 UDDI 服务器(非 IBM UDDI), 用户同样可以利用文章前面提到到两种安全机制:平台安全机制和 UDDI 安全机制来构建安全的 UDDI 应用。

IBM UDDI 与其它厂商的 UDDI 相比,有两点不同的特征:

  • 如果用户使用平台安全机制,用户就不需要设置 authentication token。也就是说,如果 IBM UDDI 服务器需要客户端请求指定 authentication token,用户只需要在 UDDI 传输端口 , 例如 UDDI_Publication_PortType, UDDI_Inquiry_PortType 上设置用户 / 密码信息就可以了。
((Stub) publishPort)._setProperty(Stub.USERNAME_PROPERTY, user);
((Stub) publishPort)._setProperty(Stub.PASSWORD_PROPERTY, password); 

而不需要如下的设置:

saveBusiness.setAuthInfo(authToken.getAuthInfo()); 

而像其它厂商的 UDDI 服务器,例如 SAP UDDI, 用户就需要根据 UDDI 服务器上的安全设置分别明确地在 UDDI API 上指定 SSL 和 authentication token 信息。

  • 对于 IBM UDDI, 用户不需要在 authentication token 中设置密码信息。但是对于其它厂商的 UDDI 服务器,例如 SAP UDDI,用户就需要明确设置密码信息。
回页首

总结

UDkeyStorePassword 认证方式 authentication token 有不同的实现方式。本文主要讲述了 IBM UDDI 产品的安全认证方式,在此基础上介绍了其它厂商的安全认证方式。相信通过本文,读者能够对 UDDI 的安全认证方式有更深入的了解。

回页首

下载

描述名字大小下载方法
样例代码Udditest.zip6.41KBHTTP
关于下载方法的信息

参考资料

学习
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值