Gerando e consumindo tokens customizados com módulos de login de emissão genérica

O gerador e o consumidor de token emitidos genericamente, GenericIssuedTokenGenerateLoginModule e GenericIssuedTokenConsumeLoginModule, podem ser usados em conjunto com as SPIs GenericSecurityTokenFactory e GenericSecurityToken para implementar uma solução de ponta a ponta para um token customizado. A geração e o consumo de tokens customizados com os Módulos de login de emissão genérica podem ser feitos com políticas e ligações ou WSSAPIs.

Antes de Iniciar

Você deverá ter um conjunto de funções de aplicativos clientes e provedores de serviço do JAX-WS no qual poderão ser incluídas classes de módulo de login do JAAS.

Sobre Esta Tarefa

Conclua as etapas a seguir se desejar ativar um conjunto de aplicativos clientes e provedores de serviço do JAX-WS para usar um token customizado. Nestas etapas, MyToken é o nome do token que está sendo criado.

Após concluir esta tarefa:
  1. Dois módulos de login do JAAS serão criados, um para gerar o token e um para consumi-lo.
  2. O token será gerado e consumido com assistência do consumidor e do gerador de token emitido genericamente.
  3. Em seguida, as restrições de segurança serão aplicadas aos aplicativos com conjuntos de políticas e ligações.

Procedimento

  1. Crie o seguinte módulo de login do JAAS do gerador e disponibilize-o ao código do aplicativo
    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. Crie o seguinte módulo de login do JAAS do consumidor e disponibilize-o ao código do aplicativo
    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");
        }
        //Obtenha o token que foi consumido pelo 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. Create new JAAS login configurations.
    1. No console administrativo, selecione Segurança->Segurança global.
    2. Em Autenticação, selecione Java Authentication and Authorization Service.
    3. Selecione Logins do sistema.
    4. Crie o gerador com o módulo customizado primeiro.
      1. Clique em Novo e, em seguida, especifique Alias = test.generate.custom.
      2. Clique em Novo e, em seguida, especifique Nome da classe do módulo = test.tokens.MyCustomGenerator.
      3. Selecione Usar proxy do módulo de login.
      4. Clique OK.
      5. Clique em Novo e, em seguida, selecione Nome da classe do módulo = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenGenerateLoginModule.
      6. Clique OK.
      7. Clique em JAAS - Logins do sistema.
    5. Crie o consumidor com o módulo customizado por último.
      1. Clique em Novo e, em seguida, especifique Alias = test.consume.custom.
      2. Clique em Novo e, em seguida, selecione Nome da classe do módulo = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenConsumeLoginModule.
      3. Clique em Novo e, em seguida, especifique Nome da classe de módulo = test.tokens.MyCustomConsumer.
      4. Selecione Usar proxy do módulo de login.
      5. Clique OK.
    6. Clique em Salvar.
  4. Crie o conjunto de políticas customizadas.
    1. No console administrativo, clique em Serviços > Conjuntos de políticas > Conjuntos de políticas de aplicativos.
    2. Clique em Novo e, em seguida, especifique ACustomTokenPolicy.
    3. Dê um clique em Aplicar.
    4. Em Políticas, clique em Incluir > WS-Security.
  5. Editar o conjunto de políticas customizadas.
    1. No console administrativo, clique em WS-Security > Política Principal.
    2. Remova os elementos não desejados:
      1. Desmarque Incluir Registro de Data e Hora no Cabeçalho de Segurança.
      2. Desmarque Proteção no nível da mensagem.
    3. Inclua o token customizado.
      1. Clique em Solicitar políticas de token
      2. Clique em Incluir tipo de token > Customizado e, em seguida, especifique:
        • Nome do token customizado = myToken
        • Parte local = MyToken
        • URI do namespace = http://www.acme.com
      3. Clique OK.
    4. Clique em Salvar.
  6. Configure o cliente para usar o conjunto de políticas ACustomTokenPolicy.
    1. No console administrativo, clique em Serviços > Clientes de serviço.
    2. Clique no cliente de serviço desejado.
    3. Selecione o recurso no nível superior.
    4. Clique em Anexar Conjunto de Políticas.
    5. Selecione ACustomTokenPolicy
  7. Crie uma ligação customizada para o cliente.
    1. Selecione o recurso no nível superior novamente.
    2. Clique em Designar Ligação.
    3. Clique em Nova Ligação Específica do Aplicativo para criar uma ligação específica do aplicativo.
    4. Especifique o nome da configuração de ligações.

      nome: customTokenClientBinding

    5. Clique em Incluir > WS-Security.

      Se o painel Principais ligações de política de segurança de mensagem não for exibido, selecione Web Services Security.

  8. Configure as ligações customizadas do cliente.
    1. Selecione Autenticação e proteção > request:myToken.
    2. Selecione Login do JAAS = test.generate.custom.
    3. Dê um clique em Aplicar.
    4. Clique em Manipulador de Retorno de Chamada.
    5. Inclua a propriedade customizada passThroughToken=true.
  9. Configure o provedor para usar o conjunto de políticas ACustomTokenPolicy.
    1. No console administrativo, clique em Serviços > Provedores de serviços.
    2. Clique no provedor de serviços desejado.
    3. Selecione o recurso no nível superior.
    4. Clique em Anexar Conjunto de Políticas.
    5. Selecione ACustomTok enPolicy.
  10. Crie uma ligação customizada para o provedor.
    1. Selecione o recurso no nível superior novamente.
    2. Clique em Designar Ligação.
    3. Clique em Nova Ligação Específica do Aplicativo para criar uma ligação específica do aplicativo.
    4. Especifique o nome da configuração de ligações.

      customTokenProviderBinding

    5. Clique em Incluir > WS-Security.

      Se o painel Principais Ligações de Política de Segurança de Mensagem não for exibido, selecione WS-Security.

  11. Configure as ligações customizadas para o provedor.
    1. Selecione Autenticação e proteção > request:myToken.
    2. Selecione Login do JAAS = test.consume.custom.
    3. Dê um clique em Aplicar.
    4. Clique em Manipulador de Retorno de Chamada.
    5. Inclua as propriedades customizadas passThroughToken=true e alwaysGeneric=true.
  12. Clique em Salvar para salvar suas alterações na configuração.
  13. Reinicie o servidor de aplicativos para aplicar as mudanças na configuração do JAAS.
  14. Teste o serviço.

Exemplo

O exemplo a seguir ilustra o cabeçalho de Segurança do SOAP que é produzido quando o procedimento anterior é seguido.

<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>

Ícone que indica o tipo de tópico Tópico de Tarefa



Ícone de registro de data e hora Última atualização: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_gen_consum_custtokens
Nome do arquivo: twbs_gen_consum_custtokens.html