生成和使用具有一般发布登录模块的定制令牌

常规发布令牌生成者和使用者(GenericIssuedTokenGenerateLoginModule 和 GenericIssuedTokenConsumeLoginModule)可以与 GenericSecurityTokenFactory 和 GenericSecurityToken SPI 一起用于为定制令牌实施端到端解决方案。可以使用策略和绑定或 WSSAPI 来生成和使用具有一般发布登录模块的定制令牌。

开始之前

您必须具有 JAX-WS 服务客户机和提供程序应用程序的功能集,您可以将新的 JAAS 登录模块类添加到其中。

关于此任务

如果您希望使一组 JAX-WS 服务客户机和提供程序应用程序可以使用定制令牌,请完成下列步骤。 在这些步骤中,MyToken 是正在创建的令牌的名称。

在您完成此任务时:
  1. 创建两个 JAAS 登录模块;一个用于生成令牌,一个用于使用令牌。
  2. 在一般发布的令牌使用者和生成者的帮助下,生成并使用该令牌。
  3. 然后,将安全性约束应用于具有策略集和绑定的应用程序。

过程

  1. 创建以下生成者 JAAS 登录模块,然后将其提供给应用程序代码
    package test.tokens;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
    import javax.security.auth.Subject;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.login.LoginException;
    import javax.security.auth.spi.LoginModule;
    import javax.xml.soap.SOAPFactory;
    import javax.xml.soap.SOAPElement;
    import javax.xml.namespace.QName;
    import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
    
    public class MyCustomGenerator implements LoginModule {
    
      private Map _sharedState;
      private Map _options;
      private CallbackHandler _handler;
    
      public void initialize(Subject subject, CallbackHandler callbackHandler,
                             Map<String, ?> sharedState, Map<String, ?> options) {
    
        this._handler = callbackHandler;
        this._sharedState = sharedState;
        this._options = options;  
      }
      public boolean login() throws LoginException {
    
        GenericSecurityTokenFactory factory = null;
        try {
          factory = GenericSecurityTokenFactory.getInstance();
        } catch (Exception e) {
          throw new LoginException(e.toString());
        }
        if (factory == null) {
          throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null");
        }
        SecurityToken myToken = null;
        try {
          SOAPElement tokenElement = createCustomElement(factory);
          myToken = factory.getToken(tokenElement, new QName("http://www.acme.com","MyToken"));
        } catch (Exception e) {
          throw new LoginException(e.toString());
        }
        if (myToken == null) {
          throw new LoginException("myToken is null");
        }
    
        //Put the token in a list on the shared state where it will be available to be used by
        //stacked login modules
        factory.putGeneratorTokenToSharedState(_sharedState, myToken);
    
        return true;
      }
    
      private SOAPElement createCustomElement(GenericSecurityTokenFactory gstFactory) throws Exception {
        /*
          <acme:MyToken xmlns:acme="http://www.acme.com" 
                xmlns:utl="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" utl:Id="cust_3">
            <acme:EMail>joe.smith@acme.com</acme:EMail>
          </acme:MyToken>
        */
        SOAPFactory factory = SOAPFactory.newInstance();
    
        //Create the MyToken element
        SOAPElement tokElement = factory.createElement("MyToken", "acme", "http://www.acme.com");
        //Add the Id attribute
        tokElement.addAttribute(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id", "utl"), gstFactory.createUniqueId());
    
        //Create the Email element
        SOAPElement emailElement = factory.createElement("Email", "acme", "http://www.acme.com");
        emailElement.addTextNode("joe.smith@acme.com");
    
        //Add the EMail element to the MyToken
        tokElement.addChildElement(emailElement);
    
        return tokElement;
      }
    
      public boolean logout() throws LoginException {
        return false;
      } 
      public boolean abort() throws LoginException {
        return false;
      }
      public boolean commit() throws LoginException {
        return true;
      }
    }
  2. 创建以下使用者 JAAS 登录模块,然后将其提供给应用程序代码
    package test.tokens;
    
    import java.util.Map;
    import javax.xml.namespace.QName;
    import org.apache.axiom.om.OMElement;
    import javax.security.auth.Subject;
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.login.LoginException;
    import javax.security.auth.spi.LoginModule;
    import com.ibm.websphere.wssecurity.callbackhandler.PropertyCallback;
    import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
    import com.ibm.wsspi.wssecurity.wssapi.OMStructure;
    
    public class MyCustomConsumer implements LoginModule {
    
      private CallbackHandler _handler;
      private Map _sharedState;
    
      public void initialize(Subject subject, CallbackHandler callbackHandler,
                             Map<String, ?> sharedState, Map<String, ?> options) {
        this._handler = callbackHandler;
        this._sharedState = sharedState;
      }
    
      public boolean login() throws LoginException {
        PropertyCallback propertyCallback = new PropertyCallback(null);
        Callback[] callbacks = new Callback[] { propertyCallback};
    
        try {
          this._handler.handle(callbacks);
        } catch (Exception e) {
          throw new LoginException(e.toString());
        }
        //Get the GenericSecurityTokenFactory
        GenericSecurityTokenFactory factory = null;
        try {
          factory = GenericSecurityTokenFactory.getInstance();
        } catch (Exception e) {
          throw new LoginException(e.toString());
        }
        if (factory == null) {
          throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null");
        }
        //Get the token that was consumed by the GenericIssuedConsumeLoginModule
        SecurityToken myToken = factory.getConsumerTokenFromSharedState(_sharedState, 
                                                                        new QName("http://www.acme.com","MyToken"));
    
        if (myToken == null) {
          throw new LoginException("no token");
        }
    
        //Get the token's element
        Object obj = myToken.getXML();
        if (obj == null) {
          throw new LoginException("token is empty");
        }
        if (!(obj instanceof OMStructure)) {
          throw new LoginException("XML is not OMStructure");
        }
        OMElement tokenElement = ((OMStructure)obj).getNode();
        //you can use the org.apache.axis2.util.XMLUtils.toDOM method
        //if you want to work with the a w3c.dom element instead of an
        //Axiom element
    
        //Do some processing on the contents of the token element
        OMElement el = tokenElement.getFirstChildWithName(new QName("http://www.acme.com","Email"));
        if (el == null) {
          throw new LoginException("no email element");
        }
        String value = el.getText();
    
        if (value != null && value.equals("joe.smith@acme.com")) {
          return true;
        } else {
          throw new LoginException("email value is bad");
        }
      }
      public boolean commit() throws LoginException {
        return true;
      }
      public boolean logout() throws LoginException {
        return false;
      }
      public boolean abort() throws LoginException {
        return false;
      }
    
    }
  3. 新建 JAAS 登录配置。
    1. 在管理控制台中,选择安全性 -> 全局安全性
    2. 在认证下,选择 Java 认证和授权服务
    3. 选择系统登录
    4. 首先创建具有定制模块的生成者。
      1. 单击新建,然后指定 Alias = test.generate.custom
      2. 单击新建,然后指定 Module class name = test.tokens.MyCustomGenerator
      3. 选择使用登录模块代理
      4. 单击确定
      5. 单击新建,然后选择模块类名 = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenGenerateLoginModule
      6. 单击确定
      7. 单击 JAAS - 系统登录
    5. 最后创建具有定制模块的使用者。
      1. 单击新建,然后指定 Alias = test.consume.custom
      2. 单击新建,然后选择模块类名 = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenConsumeLoginModule
      3. 单击新建,然后指定 Module class name = test.tokens.MyCustomConsumer
      4. 选择使用登录模块代理
      5. 单击确定
    6. 单击保存
  4. 创建定制策略集。
    1. 在管理控制台中,单击服务 > 策略集 > 应用程序策略集
    2. 单击新建,然后指定 ACustomTokenPolicy
    3. 单击应用
    4. 在“策略”下,单击添加 > WS-Security
  5. 编辑定制策略集。
    1. 在管理控制台中,单击 WS-Security > 主策略
    2. 除去不需要的元素:
      1. 取消选择在安全性头中包括时间戳记
      2. 取消选择消息级别保护
    3. 添加定制令牌。
      1. 单击请求令牌策略
      2. 单击添加令牌类型 > 定制,然后指定:
        • 定制令牌名称 = myToken
        • 局部部件 = MyToken
        • 名称空间 URI = http://www.acme.com
      3. 单击确定
    4. 单击保存
  6. 配置客户机以使用 ACustomTokenPolicy 策略集。
    1. 在管理控制台中,单击服务 > 服务客户机
    2. 单击所需的服务客户机。
    3. 选择顶级的资源。
    4. 单击连接策略集
    5. 选择 ACustomTokenPolicy
  7. 为客户机创建定制绑定。
    1. 再次选择顶级的资源。
    2. 单击指定绑定
    3. 单击新建特定于应用程序的绑定以创建特定于应用程序的绑定。
    4. 指定绑定配置名称。

      名称:customTokenClientBinding

    5. 单击添加 > WS-Security

      如果“主消息安全策略绑定”面板未显示,请选择 WS-Security

  8. 配置客户机的定制绑定。
    1. 选择认证和保护 > request:myToken
    2. 选择 JAAS 登录 = test.generate.custom
    3. 单击应用
    4. 单击回调处理程序
    5. 添加 passThroughToken=true 定制属性。
  9. 配置提供程序以使用 ACustomTokenPolicy 策略集。
    1. 在管理控制台中,单击服务 > 服务提供程序
    2. 单击所需的服务提供程序。
    3. 选择顶级的资源。
    4. 单击连接策略集
    5. 选择 ACustomTok enPolicy
  10. 为提供程序创建定制绑定。
    1. 再次选择顶级的资源。
    2. 单击指定绑定
    3. 单击新建特定于应用程序的绑定以创建特定于应用程序的绑定。
    4. 指定绑定配置名称。

      customTokenProviderBinding

    5. 单击添加 > WS-Security

      如果“主消息安全策略绑定”面板未显示,请选择 WS-Security

  11. 为提供程序配置定制绑定。
    1. 选择认证和保护 > request:myToken
    2. 选择 JAAS 登录 = test.consume.custom
    3. 单击应用
    4. 单击回调处理程序
    5. 添加 passThroughToken=truealwaysGeneric=true 定制属性。
  12. 单击保存以保存配置更改。
  13. 重新启动应用程序服务器以应用 JAAS 配置更改。
  14. 测试您的服务。

示例

以下示例说明在您遵循先前的过程时生成的 SOAP 安全头。

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
    <acme:MyToken xmlns:acme="http://www.acme.com" xmlns:utl="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" utl:Id="cust_3">
        <acme:Email>joe.smith@acme.com</acme:Email>
    </acme:MyToken>
</wsse:Security>

指示主题类型的图标 任务主题



时间戳记图标 最近一次更新时间: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_gen_consum_custtokens
文件名:twbs_gen_consum_custtokens.html