WSS API 및 메시지 레벨 보호를 사용하여 외부 STS에서 SAML 전송자 인증 토큰 요청

외부 STS(Security Token Service)에서 전송자 인증 주제 확인 메소드를 포함하는 SAML 토큰을 요청할 수 있습니다. SAML 전송자 인증 토큰을 얻은 후에는 메시지 레벨 보호와 함께 JAX-WS(Java™ API for XML-Based Web Services) 프로그래밍 모델 및 WSS API(Web Services Security API)를 사용하여 이러한 토큰을 웹 서비스 메시지 요청과 함께 전송할 수 있습니다.

시작하기 전에

이 태스크에서는 사용자가 JAX-WS 프로그래밍 모델, WSS API 인터페이스, SAML 개념, SSL 전송 보호, X.509 보안 토큰 및 웹 서비스 설정을 구성하고 관리하기 위한 정책 세트 사용에 익숙한 것으로 가정합니다.

이 태스크 정보

외부 STS에서 전송자 인증 주제 확인 메소드를 포함하는 SAML 토큰을 요청한 다음 메시지 레벨 보호와 함께 WSS API를 사용하여 웹 서비스 클라이언트에서 웹 서비스 요청 메시지로 SAML 토큰을 전송할 수 있습니다.

이 제품은 전송자 인증 주제 확인 메소드를 포함하는 SAML 토큰을 요구하는 기본 정책 세트를 제공하지 않습니다. 전송자 인증 주제 확인을 포함하는 SAML 토큰을 요구하도록 웹 서비스 보안 정책을 작성하는 방법 및 사용자 정의 바인딩 구성을 작성하는 방법에 대해 자세히 알아보려면 SAML 전송자 인증 토큰에 대한 클라이언트 및 제공자 바인딩에 대해 읽어 보십시오. 정책 및 바인딩을 웹 서비스 제공자에 첨부해야 합니다. 이 태스크에서 설명하고 있는 코드 샘플에서는 웹 서비스 제공자 정책이 SAML 토큰 및 메시지 본문 둘 다 X.509 보안 토큰을 사용하여 디지털로 서명되도록 요구하는 것으로 가정합니다.

이 태스크에서 사용되는 웹 서비스 클라이언트 애플리케이션은 다운로드 가능한 JaxWSServicesSamples 샘플 애플리케이션에 포함되어 있는 수정된 버전의 클라이언트 코드입니다. 샘플의 코드 예는 프로시저에 설명되어 있고 완전하고 즉시 사용 가능한 웹 서비스 클라이언트 샘플이 제공됩니다.

프로시저

  1. 웹 서비스 제공자를 호출하는 데 사용할 웹 서비스 클라이언트를 식별하고 얻으십시오.

    WSS API를 사용하여 SOAP 요청 메시지에 있는 SAML 토큰을 프로그래밍 방식으로 삽입하려면 이 클라이언트를 사용하십시오.

    이 프로시저에서 사용되는 웹 서비스 클라이언트는 JaxWSServicesSamples 웹 서비스 샘플 애플리케이션에 포함되어 있는 수정된 버전의 클라이언트 코드입니다.

    WSS API를 사용하여 SOAP 요청 메시지에 있는 SAML 전송자 인증 토큰을 프로그래밍 방식으로 전달하기 위해 웹 서비스 보안 API를 추가할 샘플 웹 서비스 클라이언트를 얻고 수정하려면 다음 단계를 완료하십시오.

    1. JaxWSServicesSamples 샘플 애플리케이션을 다운로드하십시오. JaxWSServicesSamples 샘플은 기본적으로 설치되지 않습니다.
    2. JaxWSServicesSamples 클라이언트 코드를 얻으십시오.

      예시를 목적으로 이 프로시저에서는 JaxWSServicesSamples 샘플에 포함되어 있는 수정된 버전의 Echo 씬 클라이언트 샘플을 사용합니다. 웹 서비스 Echo 씬 클라이언트 샘플 파일인 SampleClient.javasrc\SampleClientSei\src\com\ibm\was\wssample\sei\cli 디렉토리에 있습니다. 샘플 클래스 파일은 WSSampleClientSei.jar 파일에 포함되어 있습니다.

      JaxWSServicesSamples.ear 엔터프라이즈 애플리케이션 및 지원하는 JAR(Java Archives) 파일은 JaxWSServicesSamples 샘플 애플리케이션내 installableApps 디렉토리에 있습니다.

    3. JaxWSServicesSamples.ear 파일을 애플리케이션 서버에 배치하십시오. JaxWSServicesSamples.ear 파일 배치를 완료했으면 샘플 웹 서비스 클라이언트 코드를 샘플 애플리케이션에 대해 테스트할 준비가 된 것입니다.

    웹 서비스 클라이언트 샘플을 사용하는 대신 자신의 웹 서비스 클라이언트 애플리케이션에서 WSS API를 사용하여 SOAP 요청 메시지에 있는 SAML 토큰을 프로그래밍 방식으로 전달하기 위해 코드 스니펫을 추가하도록 선택할 수 있습니다. 이 프로시저의 예에서는 JAX-WS 웹 서비스 씬 클라이언트를 사용하지만 관리 클라이언트를 사용할 수도 있습니다.

  2. SSL 메시지 레벨 메시지 보호를 사용하도록 지정하십시오. 다음 JVM 특성을 사용하여 STS에서 SAML 토큰 요청을 보호하는 데 SSL을 사용하도록 지정하십시오.
    -Dcom.ibm.SSL.ConfigURL=file:profile_root\properties\ssl.client.props
    또는 샘플 클라이언트 코드에서 Java 시스템 특성을 사용하여 SSL 구성 파일을 정의할 수 있습니다. 예를 들면, 다음과 같습니다.
    System.setProperty("com.ibm.SSL.ConfigURL", "file:profile_root/properties/ssl.client.props");
  3. 클래스 경로에 JAX-WS JAR 파일의 씬 클라이언트를 추가하십시오. app_server_root/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar 파일을 클래스 경로에 추가하십시오. 이 JAR 파일을 클래스 경로에 추가하는 것에 대한 자세한 정보는 웹 서비스 사용 클라이언트 테스트 정보를 참조하십시오.
  4. 외부 STS에서 SAML 토큰을 요청하십시오. 다음 코드 스니펫은 SAML 전송자 인증 토큰을 요청하는 방법을 보여주고 외부 STS가 Username 토큰을 승인하고 유효성 검증한 후에 전송자 인증을 사용하는 SAML 2.0 토큰을 발행하도록 구성되는 것으로 가정합니다.
    //Request the SAML Token from external STS
    WSSFactory factory = WSSFactory.getInstance();
    String STS_URI  = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
    String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
    WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
    WSSConsumingContext concont1 = factory.newWSSConsumingContext(); 
    HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
    cbackMap1.put(SamlConstants.STS_ADDRESS, STS_URI);
    cbackMap1.put(SamlConstants.SAML_APPLIES_TO, ENDPOINT_URL);
    cbackMap1.put(SamlConstants.TRUST_CLIENT_WSTRUST_NAMESPACE, "http://docs.oasis-open.org/ws-sx/ws-trust/200512");
    cbackMap1.put(SamlConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
    cbackMap1.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML11_VALUE_TYPE);
    cbackMap1.put(SamlConstants.CONFIRMATION_METHOD, "sender-vouches");
    
    SAMLGenerateCallbackHandler cbHandler1 = new SAMLGenerateCallbackHandler(cbackMap1);
    
    // Add UNT to trust request
    UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
    SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
    
    gencont1.add(ut);
    
    cbHandler1.setWSSConsumingContextForTrustClient(concont1);
    cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
    SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, cbHandler1, "system.wss.generate.saml");
    
    System.out.println("SAMLToken id = " + samlToken.getId());
    1. WSSFactory newSecurityToken 메소드를 사용하여 외부 STS에서 SAML 토큰을 요청하는 방법을 지정하십시오.
      다음 메소드를 지정하여 SAML 토큰을 작성하십시오.
      WSSFactory  newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml")
      SAML 토큰을 요청하려면 Java 보안 권한 wssapi.SAMLTokenFactory.newSAMLToken이 필요합니다. 정책 도구를 사용하여 다음 정책 명령문을 Java 보안 정책 파일 또는 애플리케이션 클라이언트 was.policy 파일에 추가하십시오.
      permission java.security.SecurityPermission "wssapi.SAMLTokenFactory.newSAMLToken"

      SAMLToken.class 매개변수는 작성할 보안 토큰 유형을 지정합니다.

      callbackHandler 오브젝트는 요청하는 SAMLToken 토큰의 특성을 정의하는 매개변수와 STS에 연결하여 SAML 토큰을 얻기 위해 필요한 기타 매개변수를 포함합니다. SAMLGenerateCallbackHandler 오브젝트는 다음 테이블에 설명되어 있는 구성 매개변수를 지정합니다.
      표 1. SAMLGenerateCallbackHandler 특성. 이 테이블은 전송자 인증 확인 메소드를 사용하는 SAMLGenerateCallbackHandler 오브젝트의 구성 매개변수를 설명합니다.
      특성 설명 Required
      SamlConstants.CONFIRMATION_METHOD sender-vouches 확인 메소드를 사용하도록 지정합니다.
      SamlConstants.TOKEN_TYPE

      토큰 유형을 지정합니다.

      웹 서비스 클라이언트에 정책 세트 첨부가 있는 경우 이 특성은 웹 서비스 보안 런타임 환경에서 사용되지 않습니다.

      tokenGenerator 바인딩 구성의 valueType 속성을 사용하여 토큰 값 유형을 지정하십시오.

      이 프로시저의 예에서는 SAML 1.1 토큰을 사용하지만 WSSConstants.SAML.SAML20_VALUE_TYPE 값을 사용할 수도 있습니다.

      SamlConstants.STS_ADDRESS

      보안 토큰 서비스 주소를 지정합니다.

      이 태스크 주제에서 사용되는 예에서 이 특성의 값은 SAML 토큰 요청 보호를 위해 SSL을 사용하도록 지정하는 https로 설정됩니다.

      STS에서 SAML 토큰 요청을 보호하기 위해 SSL을 사용할 수 있도록 -Dcom.ibm.SSL.ConfigURL 특성을 설정해야 합니다.

      SamlConstants.SAML_APPLIES_TO SAML 토큰을 사용하려는 대상 STS 주소를 지정합니다. 아니오
      SamlConstants.TRUST_CLIENT_COLLECTION_REQUEST STS에서 RequestSecurityToken(RST) 요소로 묶인 단일 토큰을 요청할지 또는 단일 RequestSecurityTokenCollection(RSTC) 요소로 묶인 RST 콜렉션에 있는 여러 토큰을 요청할지 여부를 지정합니다.

      기본 동작은 STS에서 RequestSecurityToken(RST) 요소로 묶인 단일 토큰을 요청하는 것입니다.

      이 특성에 true 값을 지정하는 것은 STS에서 단일 RequestSecurityTokenCollection(RSTC) 요소로 묶인 RST 요소의 콜렉션에 있는 여러 토큰을 요청하는 것을 나타냅니다.

      아니오
      SamlConstants.TRUST_CLIENT_WSTRUST_NAMESPACE WS-Trust 요청에 포함된 WS-Trust 네임스페이스를 지정합니다.

      기본값은 WSTrust 1.3입니다.

      아니오

      WSSGenerationContext 인스턴스 및 WSSConsumingContext 인스턴스도 SAMLGenerateCallbackHandler 오브젝트에서 설정됩니다. WSSGenerationContext 인스턴스는 STS에 전송할 UsernameToken을 작성하기 위한 정보를 포함하는 UNTGenerateCallbackHandler 오브젝트를 포함해야 합니다.

      system.wss.generate.saml 매개변수는 SAML 토큰을 작성하기 위해 사용되는 JAAS(Java Authentication and Authorization Service) 로그인 모듈을 지정합니다. 필수 JAAS 로그인 구성을 포함하는 JAAS 구성 파일을 정의하도록 JVM 특성을 지정해야 합니다. 예를 들면, 다음과 같습니다.
      -Djava.security.auth.login.config=profile_root/properties/wsjaas_client.conf 
      또는 샘플 클라이언트 코드에서 Java 시스템 특성을 설정하여 JAAS 로그인 구성 파일을 지정할 수 있습니다. 예를 들면, 다음과 같습니다.
      System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf");
    2. 작성된 SAML 토큰의 토큰 ID를 얻으십시오.
      작성한 SAML 토큰에 대한 단순 테스트로 다음 명령문을 사용하십시오.
      System.out.println("SAMLToken id = " + samlToken.getId())
  5. SAML 토큰을 웹 서비스 요청 메시지의 SOAP 보안 헤더에 추가하십시오.
    1. 웹 서비스 클라이언트를 초기화하고 SOAPAction 특성을 구성하십시오. 다음 코드 예는 이러한 조치를 보여줍니다.
      // Initialize web services client
      EchoService12PortProxy echo = new EchoService12PortProxy();
      echo._getDescriptor().setEndpoint(endpointURL);
      
      // Configure SOAPAction properties
      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");
      			
      // Initialize WSSGenerationContext
      WSSGenerationContext gencont = factory.newWSSGenerationContext();
      gencont.add(samlToken);	
    2. WSSGenerationContext를 초기화하십시오. 다음 코드 스니펫은 생성 컨텍스트를 초기화하여 사용자가 SAMLToken을 웹 서비스 요청 메시지에 삽입할 수 있도록 하기 위해 WSSGenerationContext 유형의 gencont.object를 사용하는 것에 대해 보여줍니다.
      // Initialize WSSGenerationContext
      WSSGenerationContext gencont = factory.newWSSGenerationContext();
      gencont.add(samlToken);	
      특히 gencont.add(samlToken) 메소드 호출은 SAML 토큰을 요청 메시지에 넣도록 지정합니다. 이 조작에서 클라이언트 코드에는 다음 Java 2 Security 권한이 있어야 합니다.
       permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
  6. 웹 서비스 보안 API를 사용하여 메시지 보호를 위해 X.509 토큰을 추가하십시오.
    이 샘플 코드에서는 dsig-sender.ks 키 파일 및 SOAPRequester 샘플 키를 사용합니다. 프로덕션 환경에서는 이 샘플 키를 사용해서는 안됩니다. 다음 코드 스니펫은 메시지 보호를 위해 X.509 토큰을 추가하는 것을 보여줍니다.
    // Add an X.509 Token for message protection
        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(samlToken);
       sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
       sig.addSignPart(sigPart);                	
       sig.addSignPart(WSSSignature.BODY);
    1. X509 토큰을 포함하는 WSSSignature 오브젝트를 작성하십시오. 다음 코드 행은 X509 토큰을 포함하는 WSSSignature 오브젝트를 작성합니다.
      WSSSignature sig = factory.newWSSSignature(x509);
    2. 메시지 보호를 위해 사용할 서명된 파트를 추가하십시오. 다음 코드 행은 서명된 파트로 WSSSignature.BODY를 추가하도록 지정합니다.
      sig.addSignPart(WSSSignature.BODY);
    3. SOAP 메시지 보안 헤더에 시간소인 요소를 추가하십시오. SAML20 SenderVouches WSHTTPS 및 SAML11 SenderVouches WSHTTPS 정책 세트는 웹 서비스 요청 및 응답 메시지가 SOAP 메시지 보안 헤더로 시간소인 요소를 전달하도록 요구합니다. 다음 코드 스니펫에서 factory.newWSSTimestamp() 메소드 호출은 시간소인을 생성하고 gencont.add(timestamp) 메소드 호출은 요청 메시지에 시간소인을 추가합니다.
      // Add Timestamp
      WSSTimestamp timestamp = factory.newWSSTimestamp();
         gencont.add(timestamp);
      sig.addSignPart(WSSSignature.TIMESTAMP);
                  
      gencont.add(sig);
              	
      			
      WSSConsumingContext concont = factory.newWSSConsumingContext();
    4. STR-Transform 변환 알고리즘을 사용하여 SAML 토큰 서명을 구성하십시오.
      WSSSignPart.TRANSFORM_STRT10 속성으로 표시되는 SecurityTokenReference 변환 알고리즘을 지정하기 위해 별도의 WSSSignPart가 필요합니다. SAML 토큰은 디지털로 직접 서명할 수 없습니다. 이 속성을 사용하면 웹 서비스 보안 런타임 환경이 SAMLToken을 참조하기 위한 SecurityTokenReference 요소를 생성하고 SecurityTokenReference 변환을 사용하여 SAMLToken에 디지털로 서명할 수 있습니다. 다음 코드 행은 WSSSignPart.TRANSFORM_STRT10 속성을 사용하도록 지정합니다.
      WSSSignPart sigPart = factory.newWSSSignPart();
      sigPart.setSignPart(samlToken);
      sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
    5. WSSGenerationContext 오브젝트를 웹 서비스 RequestContext 오브젝트에 첨부하십시오. WSSGenerationContext 오브젝트에는 이제 요청 메시지를 형식화하는 데 필요한 모든 보안 정보가 들어 있습니다. gencont.process(requestContext) 메소드 호출은 WSSGenerationContext 오브젝트를 웹 서비스 RequestContext 오브젝트에 첨부하여 웹 서비스 보안 런타임 환경이 필요한 SOAP 보안 헤더를 형식화할 수 있도록 합니다. 예를 들면, 다음과 같습니다.
      // Attaches the WSSGenerationContext object to the web services RequestContext object. 
      gencont.process(requestContext);
  7. X.509 토큰을 사용하여 디지털 서명 및 응답 메시지의 무결성을 유효성 검증하십시오. 제공자 정책에서 응답 메시지의 디지털 서명을 요구하는 경우 X.509 토큰을 초기화해야 합니다.
    1. X509ConsumeCallbackHandler 오브젝트는 제공자 디지털 서명을 유효성 검증하기 위해 신뢰 저장소, dsig-receiver.ks 및 인증서 경로 오브젝트를 사용하여 초기화됩니다. 다음 코드 행은 X509ConsumeCallbackHandler 오브젝트를 초기화하는 데 사용됩니다.
      X509ConsumeCallbackHandler callbackHandlerVer = new X509ConsumeCallbackHandler( 
       "profile_root/etc/ws-security/samples/dsig-receiver.ks",
                "JKS",
                 "server".toCharArray(),
                  certList,
                        java.security.Security.getProvider("IBMCertPath"));
    2. WSSVerification 오브젝트가 작성되고 메시지 본문이 확인 오브젝트에 추가되어 웹 서비스 보안 런타임 환경이 디지털 서명을 유효성 검증합니다.
      다음 코드 행은 WSSVerification 오브젝트를 초기화하는 데 사용됩니다.
      WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
      WSSConsumingContext 오브젝트에는 이제 요청 메시지를 형식화하는 데 필요한 모든 보안 정보가 들어 있습니다. concont.process(requestContext) 메소드 호출은 WSSConsumingContext 오브젝트를 응답 메소드에 첨부합니다. 예를 들면, 다음과 같습니다.
      // Attaches the WSSConsumingContext object to the web services RequestContext object. 
      concont.process(requestContext);

결과

외부 STS에서 전송자 인증 확인 메소드를 포함하는 SAML 토큰을 요청했습니다. 토큰을 얻은 후에 JAX-WS 프로그래밍 모델 및 WSS API를 사용하는 메시지 레벨 보호를 사용하여 웹 서비스 요청 메시지와 함께 토큰을 전송했습니다.

다음 코드 샘플은 외부 STS로부터 SAML 토큰을 요청하는 방법을 보여주고 메시지 레벨 보호와 함께 웹 서비스 요청 메시지로 해당 SAML 토큰을 전송하는 완전하고 즉시 사용 가능한 웹 서비스 클라이언트 애플리케이션입니다. 이 샘플 코드는 이전에 설명한 프로시저 단계를 보여줍니다.

/**
 * The following source code is sample code created by IBM Corporation.  
 * This sample code is provided to you solely for the purpose of assisting you in the  
 * use of the technology.  The code is provided 'AS IS', without warranty or condition of 
 * any kind.  IBM shall not be liable for any damages arising out of your use of the 
 * sample code, even if IBM has been advised of the possibility of such damages.
 */
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.callbackhandler.SAMLGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
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.SAMLToken;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.websphere.wssecurity.callbackhandler.X509ConsumeCallbackHandler;
import com.ibm.websphere.wssecurity.callbackhandler.X509GenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.WSSException;
import com.ibm.websphere.wssecurity.wssapi.signature.WSSSignPart;
import com.ibm.websphere.wssecurity.wssapi.signature.WSSSignature;
import com.ibm.websphere.wssecurity.wssapi.verification.WSSVerification;
import com.ibm.websphere.wssecurity.wssapi.token.X509Token;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.saml.config.SamlConstants;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertStore;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.Set;
import java.util.HashMap;
import java.util.Map;

import javax.xml.ws.BindingProvider;

public class SampleSamlSVClient {
	private String urlHost = "localhost";
	private String urlPort = "9080";
	private static final String CONTEXT_BASE = "/WSSampleSei/";
	private static final String ECHO_CONTEXT12 = CONTEXT_BASE+"EchoService12";	
	private String message = "HELLO";
	private String uriString = "http://" + urlHost + ":" + urlPort;
	private String endpointURL = uriString + ECHO_CONTEXT12;
	private String input = message;

	/**
	 * main()
	 * 
	 * see printusage() for command-line arguments
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		SampleSamlSVClient sample = new SampleSamlSVClient();
		sample.CallService();
	}

	/**
	 * CallService Parms were already read. Now call the service proxy classes. 
	 * 
	 */
	void CallService() {
		String response = "ERROR!:";
		try {
			    System.setProperty("com.ibm.SSL.ConfigURL", "profile_root/properties/ssl.client.props");
			    System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas.conf");
			

//Request the SAML Token from external STS
WSSFactory factory = WSSFactory.getInstance();
String STS_URI  = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext(); 
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(SamlConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(SamlConstants.SAML_APPLIES_TO, ENDPOINT_URL);
cbackMap1.put(SamlConstants.TRUST_CLIENT_WSTRUST_NAMESPACE, "http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(SamlConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
cbackMap1.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML11_VALUE_TYPE);
cbackMap1.put(SamlConstants.CONFIRMATION_METHOD, "sender-vouches");

SAMLGenerateCallbackHandler cbHandler1 = new SAMLGenerateCallbackHandler(cbackMap1);

// Add UNT to trust request
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);

gencont1.add(ut);

cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, cbHandler1, "system.wss.generate.saml");

System.out.println("SAMLToken id = " + samlToken.getId());                        
			
	        // Initialize web services client. 
			EchoService12PortProxy echo = new EchoService12PortProxy();
			echo._getDescriptor().setEndpoint(endpointURL);

			// Configure SOAPAction properties 
			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");
			
			// Initialize WSSGenerationContext
			WSSGenerationContext gencont = factory.newWSSGenerationContext();
	        gencont.add(samlToken);		        
	        
	        // Add X.509 Tokens for message protection
            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(samlToken);
            sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
            sig.addSignPart(sigPart);                	
            sig.addSignPart(WSSSignature.BODY);
            
	        // Add timestamp
	        WSSTimestamp timestamp = factory.newWSSTimestamp();
			gencont.add(timestamp);
        	sig.addSignPart(WSSSignature.TIMESTAMP);
            
        	gencont.add(sig);
        	
			
        	WSSConsumingContext concont = factory.newWSSConsumingContext();
        	
        	// Prepare to consume timestamp in response message
	     	concont.add(WSSConsumingContext.TIMESTAMP); 
	        
	     	// Prepare to verify digital signature in response message        	
	        X509Certificate x509cert = null;
	        try {
	                InputStream is = new FileInputStream("profile_root/etc/ws-security/samples/intca2.cer");
	                CertificateFactory cf = CertificateFactory.getInstance("X.509");
	                x509cert = (X509Certificate) cf.generateCertificate(is);
	        } catch (FileNotFoundException e1) {
	                throw new WSSException(e1);
	        } catch (CertificateException e2) {
	                throw new WSSException(e2);
	        }
	        Set<Object> eeCerts = new HashSet<Object>();
	        eeCerts.add(x509cert);

	        java.util.List<CertStore> certList = new java.util.ArrayList<CertStore>();
	        CollectionCertStoreParameters certparam = new CollectionCertStoreParameters(eeCerts);

	        CertStore cert = null;
	        try {
	                cert = CertStore.getInstance("Collection", certparam, "IBMCertPath");
	        } catch (NoSuchProviderException e1) {
	                throw new WSSException(e1);
	        } catch (InvalidAlgorithmParameterException e2) {
	                throw new WSSException(e2);
	        } catch (NoSuchAlgorithmException e3) {
	                throw new WSSException(e3);
	        }
	        if (certList != null) {
	                certList.add(cert);
	        }

	        X509ConsumeCallbackHandler callbackHandlerVer = new X509ConsumeCallbackHandler(
	        		"profile_root/etc/ws-security/samples/dsig-receiver.ks",
	        		"JKS",
	        		"server".toCharArray(),
	        		certList,
	        		java.security.Security.getProvider("IBMCertPath"));

	        WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);

	        ver.addRequiredVerifyPart(WSSVerification.BODY);
	        concont.add(ver);
						
	        gencont.process(requestContext);
	        concont.process(requestContext);
	        
	        // Build the input object
			EchoStringInput echoParm = 
				new com.ibm.was.wssample.sei.echo.ObjectFactory().createEchoStringInput();
			echoParm.setEchoInput(input);
			System.out.println(">> CLIENT: SEI Echo to " + endpointURL);		
						
			// Call the service
			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();
		}
	}
}
이 웹 서비스 클라이언트 애플리케이션 샘플이 정확하게 실행되면 다음 메시지와 같은 메시지를 수신하게 됩니다.
SAMLToken id = _6CDDF0DBF91C044D211271166233407
Retrieving document at 'file:profile_root/.../wsdl/'.
>> CLIENT: SEI Echo to http://localhost:9443/WSSampleSei/EchoService12
>> CLIENT: SEI Echo invocation complete.
>> CLIENT: SEI Echo response is: SOAP12==>>HELLO

주제 유형을 표시하는 아이콘 태스크 주제



시간소인 아이콘 마지막 업데이트 날짜: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_configsamlsendervouches_msglevel_requeststs
파일 이름:twbs_configsamlsendervouches_msglevel_requeststs.html