É possível solicitar um token de autenticação a partir de um Security
Token Service (STS) externo e, em seguida, enviar o token com mensagens de solicitação
de serviço da web usando o modelo de programação Java™ API
for XML-Based Web Services (JAX-WS) e APIs Web Services
Security (API WSS), com proteção no nível de mensagem ou transporte.
Antes de Iniciar
Essa tarefa assume que você é familiarizado com o modelo de programação JAX-WS, as interfaces API WSS, os módulos de login de token de segurança genérico de segurança de serviço da Web WebSphere, proteção de transporte SSL, proteção de nível de mensagem, e o uso de conjuntos de política para configurar e administrar configurações de serviços da Web.
Sobre Esta Tarefa
O aplicativo cliente de serviço da Web usado nessa tarefa
é uma versão modificada do código do cliente que está contida no
aplicativo de amostra JaxWSServicesSamples que está disponível para download.
Fragmentos de código da amostra são descritos na seção de procedimento, e uma amostra de cliente de serviços da Web completa e pronta para usar é fornecida.
Conclua as etapas
a seguir para solicitar um token de autenticação de Acesso do SAML a partir de um
STS externo e envie o token:
Procedimento
- Identifique e obtenha o cliente de serviços da Web que deseja usar para chamar um provedor de serviços da Web. Use esse cliente para pedir e inserir tokens de autenticação em mensagens de pedido SOAP programaticamente usando APIs WSS. O cliente de serviço da Web usado nesse procedimento
é uma versão modificada do código do cliente que está contida no
aplicativo de amostra de serviço da Web JaxWSServicesSamples.
Conclua as seguintes etapas para obter e modificar o cliente de serviço da Web de amostra para incluir a API de Segurança de Serviços da Web para passar um token de segurança na mensagem de pedido SOAP programaticamente usando APIs WSS:
- Fazer download do aplicativo de amostra JaxWSServicesSamples. A amostra JaxWSServicesSamples não é instalada por padrão.
- Obter o código do cliente JaxWSServicesSamples. Para o propósito desse exemplo, o procedimento usa uma versão modificada da amostra do thin client Echo que está incluída na amostra JaxWSServicesSamples. O arquivo de amostra do thin client Echo de serviço da Web, SampleClient.java, está localizado no diretório src\SampleClientSei\src\com\ibm\was\wssample\sei\cli. O arquivo de classe de amostra é incluído no arquivo WSSampleClientSei.jar.
O aplicativo corporativo JaxWSServicesSamples.ear
e os arquivos Java Archives de suporte
estão localizados no diretório installableApps no aplicativo
de amostra JaxWSServicesSamples.
- Implementar o arquivo JaxWSServicesSamples.ear
no servidor de aplicativos. Após implementar o arquivo JaxWSServicesSamples.ear,
você está pronto para testar o código do cliente de serviço da Web de amostra em relação
ao aplicativo de amostra.
Em vez de usar o Conjunto de Políticas para a proteção da amostra do cliente de serviço da Web, é possível escolher incluir os fragmentos de código para passar tokens de autenticação na mensagem de pedido SOAP programaticamente usando APIs WSS em seu próprio aplicativo de cliente de serviço da Web. O exemplo nesse procedimento usa um thin cliente de serviços da Web JAX-WS; porém, também é possível usar um cliente gerenciado.
- Conecte o conjunto de políticas padrão SAML11 Bearer WSHTTPS ao provedor de serviços da Web. Esse conjunto de políticas é usado para proteger mensagens usando transporte HTTPS. Consulte sobre a configuração de ligações de cliente e provedor para o token SAML Bearer para obter detalhes sobre como conectar o conjunto de políticas SAML11 Bearer WSHTTPS padrão ao provedor de serviços da Web.
- Designe as ligações gerais padrão de amostra SAML Bearer Provider para o provedor de serviços da Web de amostra. Consulte sobre a configuração de ligações de cliente e provedor para o token de transmissão SAML para obter detalhes sobre como designar as ligações gerais padrão da amostra SAML Bearer Provider para o seu aplicativo de serviços da Web.
- Verifique se as propriedades customizadas trustStoreType, trustStorePassword e trustStorePath correspondem ao armazenamento de confiança que contém o certificado de assinante STS. Conclua as seguintes etapas usando o console administrativo:
- Clique em .
- Clique em con_saml11token na tabela Tokens de Autenticação.
- Clique em Manipulador de Retorno de Chamada.
- Na seção Propriedades Customizadas, certifique-se de que as propriedades customizadas trustStoreType, trustStorePassword e trustStorePath correspondem ao armazenamento de confiança que contém o certificado do assinante STS.
- Se estiver usando proteção de nível de Transporte SSL para proteger o pedido de serviço da Web ou o pedido de WS-Trust, use a seguinte propriedadeJava virtual machine (JVM) para definir a configuração SSL.
-Dcom.ibm.SSL.ConfigURL=file:<profile_root>\properties\ssl.client.props
Alternativamente, é possível definir o arquivo de configuração SSL usando uma propriedade de sistema Java no código do cliente de amostra:
System.setProperty("com.ibm.SSL.ConfigURL", "file:profile_root/properties/ssl.client.props");
- Inclua o arquivo JAR para thin client do JAX-WS no caminho da classe: app_server_root/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar. Consulte as informações sobre o teste dos clientes ativados para serviços da Web para obter informações adicionais sobre como incluir esse arquivo JAR no caminho da classe.
- Peça o token de autenticação de um STS externo. O seguinte fragmento de código ilustra como pedir o token de autenticação a ser usado com o módulo de login do Token de segurança genérico do WebSphere, e assume que um STS externo está configurado para aceitar um token de nome de usuário como token de autenticação, e para emitir um token SAML 1.1.
//Pedir SecurityToken de STS externo:
WSSFactory factory = WSSFactory.getInstance();
//URL do STS que emite o token solicitado
sequência STS_URI = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
//Terminal dos serviços da Web que recebe o token emitido
Sequência ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
//Começar o código de amostra 1 (Usando WS-Trust Issue para pedir o token do
//STS para o qual o token de autenticação é enviado sobre cabeçote WS-Security):
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//A seguinte propriedade especifica que o pedido ws-trust deve estar
//em conformidade com a especificação WS-Trust 1.3
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//Esse pedido é feito com apenas WS-TRust Issue (sem o uso do
//WS-Trust Validate)
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Crie o objeto de contexto para pedido WS-Trust:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT para autenticação de pedido de confiança
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//Final do código de amostra 1.
//Comece o código de amostra 2 (usando WS-Trust Validate para pedir um token
//trocando um token em RunAs Subject).
//Se o cliente de serviço da Web tiver RunAs Subject, por exemplo, um
//servidor intermediário autenticado age como um cliente para chamar o
//serviço de recebimento de dados, é possível programar o cliente para usar o token a partir
//do RunAs subject para trocar com o STS usando WS-Trust validate.
//Para fazer isso, você substitui o código de amostra 1 pelo seguinte:
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//Esse pedido é feito com o WS-Trust 1.3
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//inclua a próxima linha se não desejar fallback para WS-Trust Issue se
//a troca de token falhar.
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY, "true");
//inclua a próxima linha para especificar o tipo de token no RunAs subject que
//será usado para trocar o token pedido. Por exemplo, você use
//o token LTPA para trocar por um token SAML. Se o token trocado
//no RunAs subject tiver o mesmo tipo de valor do token pedido,
//configurar IssuedTokenConfigConstants.USE_TOKEN não é necessário.
cbackMap1.put(IssuedTokenConfigConstants.USE_TOKEN, LTPAToken.ValueType);
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Os seguintes códigos são incluídos se o token de Autenticação no cabeçote ws-security
//ou proteção de segurança de nível de mensagem for necessário. Se não houver nenhuma
//proteção de nível de mensagem ou token de autenticação adicional para
//WS-Trust Validate, não crie o objeto de contexto mostrado abaixo.
//Objeto de contexto para pedido WS-Trust:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT para autenticação de pedido de confiança
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//Final do código de amostra 2.
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
//A etapa a seguir é necessária para configurar o ValueType.
//O parâmetro sempre é o QName do valueType do token solicitado.
//QName para SAML1.1:
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//Inclui definições do QName para SAML11, SAML20, TAM
//, e token Pass ticket.
//QName para SAML 2.0:
QName Saml20ValueType = new QName(WSSConstants.SAML.SAML20_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//QName para token TAM:
QName TamValueType = new QName("http://ibm.com/2004/01/itfim/ivcred");
//QName para token PassTicket:
QName PassTicketValueType = new QName("http://docs.oasis-open.org/wss/
2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken");
//É possível usar a interface de Token para obter o QName ValueType para
//todos os outros tokens. Por exemplo, o QName de um Token Username é //UsernameToken.ValueType.
O objeto GenericIssuedTokenGenerateCallbackHandler contém parâmetros que definem as características do token de segurança que você está pedindo e outros parâmetros necessários para atingir o STS e obter o token de segurança. O objeto GenericIssuedTokenGenerateCallbackHandler especifica os parâmetros de configuração descritos na tabela a seguir:
Tabela 1. Propriedades do GenericIssuedTokenGenerateCallbackHandler. Essa tabela descreve os parâmetros de configuração para o objeto GenericIssuedTokenGenerateCallbackHandler e especifica se a propriedade é necessária ou não.Propriedade |
Description |
Required |
IssuedTokenConfigConstants.STS_ADDRESS |
Especifica o endereço http do STS. Quando a comunicação com o STS é protegida com SSL, você deve configurar a propriedade -Dcom.ibm.SSL.ConfigURL. A comunicação SSL com o STS é indicada com um prefixo de endereço https://.
|
Sim |
IssuedTokenConfigConstants.APPLIES_TO |
Especifica o endereço do serviço de destino para onde deseja usar o token. |
Não |
IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST |
Especifica se pedir do STS um token único que esteja integrado em um elemento RequestSecurityToken (RST) ou diversos tokens em uma coleção de elementos RST que estão integrados em um único elemento RequestSecurityTokenCollection (RSTC). O comportamento padrão é pedir um único token que esteja integrado em um elemento RequestSecurityToken (RST) do STS.
Especificar um valor true para essa propriedade indica pedir diversos tokens em uma coleção de elementos RST que estão integrados em um único elemento RequestSecurityTokenCollection (RSTC) do STS.
O valor padrão é false.
|
Não |
IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE |
Especifica o namespace WS-Trust que é incluído no pedido WS-Trust. O valor padrão é WSTrust 1.3.
|
Não |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT |
Especifique se deseja que WS-Security use o token a partir do RunAs subject para trocar o token pedido primeiro usando WS-Trust Validate. Se configurado para false, WS-Security usará WS-Trust Issue para pedir o token. O valor padrão é true.
|
Não |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY |
Especifique se você não deseja que o WS-Security use WS-Trust Issue para o token solicitado se a troca de token falhar. O valor padrão é false.
|
Não |
IssuedTokenConfigConstants.USE_TOKEN |
Use esse valor para escolher um token do RunAs subject para trocar o token solicitado. O valor padrão é o ValueType do token solicitado.
|
Não |
Uma instância de WSSGenerationContext e uma instância de WSSConsumingContext também são configuradas no objeto GenericIssuedTokenGenerateCallbackHandler. Nesse exemplo, a instância WSSGenerationContext contém um objeto UNTGenerateCallbackHandler com as informações para criar o UsernameToken que você deseja enviar para o STS.
O parâmetro
system.wss.generate.issuedToken especifica o módulo de login Java Authentication
and Authorization Service (JAAS) que é usado para criar o token de segurança genérico. Você deve especificar uma propriedade JVM para definir um
arquivo de configuração JAAS que contém a configuração de login JAAS necessária;
por exemplo:
-Djava.security.auth.login.config=profile_root/properties/wsjaas_client.conf
Alternativamente, é possível especificar um arquivo de configuração de login do JAAS definindo uma propriedade do sistema Java no código do cliente de amostra; por exemplo:
System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf");
- Inclua o token de autenticação solicitado do STS para o cabeçalho de segurança SOAP de mensagens de pedido de serviços.
- Inicialize o cliente dos serviços da Web e configure as propriedades SOAPAction. O seguinte código ilustra essas ações:
// Inicializar o cliente de serviços da Web
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// Configurar propriedades SOAPAction
BindingProvider bp = (BindingProvider) (echo._getDescriptor().getProxy());
Map<String, Object> requestContext = bp.getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoOperation");
// Inicializar WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
- Inicializar o objeto WSSGenerationContext. O seguinte código ilustra o uso do método WSSFactory.newWSSGenerationContext para obter um objeto WSSGenerationContext. O objeto WSSGenerationContext é então usado para inserir o token em uma mensagem de pedido de serviço da Web:
// Inicializar WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
O método WSSGenerationContext.add requer que o código do cliente tenha a seguinte permissão de Segurança Java 2:permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
- Inclua um token X.509 para proteção de mensagens (ignore esta etapa
se o serviço da web é protegido apenas com proteção no nível do Transporte
SSL). O seguinte código de amostra usa o arquivo-chave dsig-sender.ks e a chave de amostra SOAPRequester. Você não deve usar a chave de amostra em um ambiente de produção. O seguinte código ilustra a inclusão de um token X.509 para proteção de mensagem:
// Incluir um Token X.509 para proteção de mensagem
X509GenerateCallbackHandler x509callbackHandler = new X509GenerateCallbackHandler(
null,
"profile_root/etc/ws-security/samples/dsig-sender.ks",
"JKS",
"client".toCharArray(),
"soaprequester",
"client".toCharArray(),
"CN=SOAPRequester, OU=TRL, O=IBM, ST=Kanagawa, C=JP", null);
SecurityToken x509 = factory.newSecurityToken(X509Token.class,
x509callbackHandler, "system.wss.generate.x509");
WSSSignature sig = factory.newWSSSignature(x509);
sig.setSignatureMethod(WSSSignature.RSA_SHA1);
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
sig.addSignPart(sigPart);
sig.addSignPart(WSSSignature.BODY);
- Crie um objeto WSSSignature com o token X.509. A seguinte linha de código cria um objeto WSSSignature com o token X.509:
WSSSignature sig = factory.newWSSSignature(x509);
- Inclua a parte assinada para usar para proteção de mensagem. A seguinte linha de código especifica para incluir WSSSignature.BODY como a parte assinada:
sig.addSignPart(WSSSignature.BODY);
- Inclua o elemento Timestamp no cabeçalho de Segurança do SOAP. O conjunto de políticas SAML20 SenderVouches WSHTTPS e SAML11 SenderVouches WSHTTPS requer que pedidos e respostas de serviços da Web contenham um elemento Timestamp no cabeçalho de Segurança do SOAP. No código a seguir, o métodoWSSFactory.newWSSTimestamp() gera um elemento Timestamp, e o método WSSGenerationContext.add(timestamp) inclui o elemento Timestamp na mensagem de pedido:
// Incluir elemento Timestamp
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
- Ignore essa etapa se a assinatura do token não for necessária. Se o token de segurança solicitado precisar ser assinado com a opção de referência STR
Dereference Transform, siga a etapa 1. Caso contrário, siga a etapa 2. A opção de referência STR Dereference Transform é comumente conhecida como STR-Transform.
Etapa 1: Alguns tokens, incluindo Tokens SAML, não podem ser assinados digitalmente diretamente. Você deve assinar o token usando STR-Transform. Para que um token seja assinado com STR-Transform, ele deve ser referenciado por um elemento <wsse:SecurityTokenReference> no bloco de cabeçalho <wsse:Security>. Para assinar um token de segurança com STR-Transform, um WSSSignPart separado é criado para especificar o SecurityTokenReference com um algoritmo de transformação que é representado pelo atributo WSSSignPart.TRANSFORM_STRT10. Esse atributo ativa o ambiente de tempo de execução da WS-Security para gerar um elemento SecurityTokenReference para referenciar o token e assinar digitalmente o token usando a STR Dereference. O código a seguir ilustra o uso do atributo WSSSignPart.TRANSFORM_STRT10:
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
Etapa 2: Se o token assinado solicitado não for um token SAML, ou STR-Transform não for usado, use o seguinte código no lugar:sig.addSignPart(token);
- Conecte o objeto WSSGenerationContext ao objeto RequestContext do serviço da Web. O objeto WSSGenerationContext agora contém as informações de segurança que são necessárias para formatar uma mensagem de pedido. O método WSSGenerationContext.process(requestContext) conecta o objeto WSSGenerationContext ao objeto RequestContext do serviço da Web para ativar o ambiente de tempo de execução da WS-Security para formatar o cabeçalho de Segurança SOAP necessário; por exemplo:
// Conecta o objeto WSSGenerationContext ao objeto RequestContext do serviço da Web.
gencont.process(requestContext);
- Use o token X.509 para validar a assinatura digital e
a integridade da mensagem de resposta se a política do provedor requer
que a mensagem de resposta seja assinada digitalmente. Ignore essa etapa se usar proteção de nível de Transporte SSL.
- Um objeto X509ConsumeCallbackHandler é inicializado com um armazenamento de confiança e uma Lista de objetos do caminho do certificado para validar a assinatura digital em uma mensagem de resposta. O seguinte código inicializa o objeto X509ConsumeCallbackHandler com armazenamento de confiança dsig-receiver.ks e um objeto do caminho do certificado chamado certList:
ArrayList certList = new ArrayList();
java.security.cert.CertStore certStore = java.security.cert.CertStore.getDefaultType();
certList.add(certStore);
X509ConsumeCallbackHandler callbackHandlerVer = new
X509ConsumeCallbackHandler("profile_root/etc/ws-security/samples/dsig-receiver.ks",
"JKS",
"server".toCharArray(),
certList,
java.security.Security.getProvider("IBMCertPath"));
- Um objeto WSSVerification é criado e o corpo da mensagem é incluído ao objeto de verificação para que o ambiente de tempo de execução da WS-Security valide a assinatura digital. O seguinte código é usado para inicializar o objeto WSSVerification:
WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
O objeto WSSConsumingContext agora contém as informações de segurança que são necessárias para formatar uma mensagem de pedido. O método WSSConsumingContext.process(requestContext) conecta o objeto WSSConsumingContext ao método de resposta; por exemplo:// Conecta o objeto WSSConsumingContext ao objeto RequestContext do serviço da Web.
concont.process(requestContext);
Resultados
Você solicitou um token de segurança de um STS externo. Após obter o token,
você enviou o token com mensagens de solicitação de serviço da web usando a
proteção no nível da mensagem usando o modelo de programação JAX-WS e as WSS APIs.
Exemplo
O exemplo de código a seguir é um aplicativo cliente de serviço da web
que demonstra como solicitar um token de Acesso do SAML a partir de um
STS externo e enviar esse token SAML em uma mensagem de solicitação de serviço da web. Se o seu cenário de uso necessitar de tokens SAML, mas não necessitar que o seu aplicativo passe os tokens SAML usando mensagens de serviços da Web, você apenas precisa usar a primeira parte do seguinte código de amostra, a partir da seção
// Inicializar cliente do serviço da Web.
package com.ibm.was.wssample.sei.cli;
import com.ibm.was.wssample.sei.echo.EchoService12PortProxy;
import com.ibm.was.wssample.sei.echo.EchoStringInput;
import com.ibm.websphere.wssecurity.wssapi.WSSConsumingContext;
import com.ibm.websphere.wssecurity.wssapi.WSSFactory;
import com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext;
import com.ibm.websphere.wssecurity.wssapi.WSSTimestamp;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
import com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.core.config.IssuedTokenConfigConstants;
import com.ibm.websphere.wssecurity.callbackhandler.GenericIssuedTokenGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityToken;
import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.Map;
import javax.xml.ws.BindingProvider;
public class SampleSamlSVClient {
private String urlHost = "yourhost";
private String urlPort = "9444";
private static final String CONTEXT_BASE = "/WSSampleSei/";
private static final String ECHO_CONTEXT12 = CONTEXT_BASE+"EchoService12";
private String message = "HELLO";
private String uriString = "https://" + urlHost + ":" + urlPort;
private String endpointURL = uriString + ECHO_CONTEXT12;
private String input = message;
/**
* main()
*
* consulte printusage() para argumentos de linha de comandos
*
* @param args
*/
public static void main(String[] args) {
SampleSamlSVClient sample = new SampleSamlSVClient();
sample.CallService();
}
/**
* Os CallService Parms já foram lidos. Agora chame as classes proxy do serviço
*
*/
anular CallService() {
Resposta de sequência = "ERROR!:";
try {
System.setProperty("java.security.auth.login.config",
"file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/wsjaas_client.conf ");
System.setProperty("com.ibm.SSL.ConfigURL",
"file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/ssl.client.props");
//Pedir o SAML Token a partir de STS externo
WSSFactory factory = WSSFactory.getInstance();
String STS_URI = "https://yourhost:9443/TrustServerWST13/services/RequestSecurityToken";
String ENDPOINT_URL = "http://localhost:9081/WSSampleSei/EchoService12";
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Objeto de contexto para pedido WS-Trust:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT para autenticação de pedido de confiança
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//obtenha token de segurança genérico
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
System.out.println("SAMLToken id = " + token.getId());
// Inicializar o cliente de serviços da Web
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// Configurar propriedades SOAPAction
BindingProvider bp = (BindingProvider) (echo._getDescriptor().getProxy());
Map<String, Object> requestContext = bp.getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoOperation");
// Inicializar WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
// Incluir registro de data e hora
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
gencont.process(requestContext);
// Construir o objeto de entrada
EchoStringInput echoParm =
new com.ibm.was.wssample.sei.echo.ObjectFactory().createEchoStringInput();
echoParm.setEchoInput(input);
System.out.println(">> CLIENT: SEI Echo to " + endpointURL);
// Preparar para consumir registro de data e hora em mensagem de resposta.
WSSConsumingContext concont = factory.newWSSConsumingContext();
concont.add(WSSConsumingContext.TIMESTAMP);
concont.process(requestContext);
// Chamar o serviço
response = echo.echoOperation(echoParm).getEchoResponse();
System.out.println(">> CLIENT: SEI Echo invocation complete.");
System.out.println(">> CLIENT: SEI Echo response is: " + response);
} catch (Exception e) {
System.out.println(">> CLIENT: ERROR: SEI Echo EXCEPTION.");
e.printStackTrace();
}
}
}