SSL 전송 보호와 함께 WSS API를 사용하여 자체 발행 SAML 전송자 인증 토큰 전송

전송자 인증 주제 확인 메소드를 포함한 자체 발행 SAML 토큰을 작성한 다음 전송 보호와 함께 JAX-WS(Java™ API for XML-Based Web Services) 프로그래밍 모델 및 WSS API(Web Services Security API)를 사용하여 웹 서비스 요청 메시지와 해당 토큰을 전송할 수 있습니다.

시작하기 전에

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

이 태스크 정보

웹 서비스 보안 프로그래밍 인터페이스를 사용하여 SOAP 요청 메시지에서 전송자 인증 주제 확인 메소드를 포함하는 SAML 토큰을 사용하도록 웹 서비스 클라이언트를 빌드할 수 있습니다. 웹 서비스 클라이언트에서 프로그래밍 인터페이스를 사용하여 전송 레벨에서 메시지 보호를 사용하는 전송자 인증 주제 확인에 SAML 토큰의 사용을 지정하는 것은 정책 세트 및 바인딩 구성을 사용하는 것에 대한 대안적 접근법입니다.

자체 발행 SAML 토큰을 작성한 다음 웹 서비스 클라이언트에서 웹 서비스 요청 메시지로 SAML 토큰을 전송할 수 있습니다. 이 태스크에서 사용되는 웹 서비스 클라이언트 애플리케이션은 다운로드 가능한 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. SAML20 전달자 WSHTTPS 기본 정책 세트 또는 SAML11 전달자 WSHTTPS 기본 정책 세트의 사본을 작성하십시오.

    이 새 정책 세트가 전송자 인증 확인 메소드를 사용하는지 식별하는 데 도움이 되는 정책 세트의 사본 이름(예: SAML20 SenderVouches WSHTTPS 또는 SAML11 SenderVouches WSHTTPS)을 제공하십시오.

    정책에서가 아니라 바인딩 구성에서 주제 확인 메소드가 지정되기 때문에 새 정책 파일에 대한 추가 변경이 필요하지 않습니다.

    새 정책 파일은 정책 ID로 SAMLToken20Bearer 또는 SAMLToken11Bearer를 포함합니다. SAMLToken20Bearer 정책의 ID를 SAMLToken20SV로 변경하거나 SAMLToken11Bearer 정책의 ID를 SAMLToken11SV로 변경하여 보다 서술적인 이름을 지정하십시오. 정책의 ID를 변경해도 정책 시행은 어떤 방식으로든 변경되지 않습니다. 그러나 설명 ID를 추가하면 이러한 정책 ID가 전송자 인증 확인 메소드를 사용하는지 식별하는 데 도움이 됩니다.

    이러한 정책의 설정을 보려는 경우 관리 콘솔을 사용하여 다음 조치를 완료하십시오.
    1. 서비스 > 정책 세트 > 애플리케이션 정책 세트 > policy_set_name을 클릭하십시오.
    2. 정책 테이블에서 WS-Security 정책을 클릭하십시오.
    3. 기본 정책 링크 또는 부트스트랩 정책 링크를 클릭하십시오.
    4. 정책 세부사항 섹션에서 토큰 정책 요청을 클릭하십시오.
  3. 새 SAML20 SenderVouches WSHTTPS 또는 SAML11 SenderVouches WSHTTPS 정책 세트를 웹 서비스 제공자 애플리케이션에 첨부하십시오. 이 정책 세트를 웹 서비스 제공자 애플리케이션에 첨부하는 것에 대한 세부사항은 SAML 전송자 인증 토큰에 대한 클라이언트 및 제공자 바인딩 구성에 대해 읽어 보십시오.
  4. SAML 전달자 제공자 샘플 기본 일반 바인딩의 사본을 작성하십시오.
    1. 기본 정책 세트의 새 사본에 SAML Sender-vouches provider binding과 같이 전송자 인증을 포함하는 이름을 제공하십시오.
    2. 원하는 SAML 토큰 버전의 토큰 이용자 구성에서 confirmationMethod 특성의 값을 sender-vouches로 변경하십시오. 인증 요구사항을 충족시키기 위한 전송자 인증 바인딩 수정에 대한 세부사항은 SAML 전송자 인증 토큰에 대한 클라이언트 및 제공자 바인딩 구성에 대해 읽어 보십시오.
  5. 새 제공자 바인딩을 JaxWSServicesSamples 제공자 샘플에 지정하십시오. SAML 전달자 인증 제공자 샘플, 기존 일반 바인딩을 웹 서비스 제공자 애플리케이션에 지정하는 것에 대한 세부사항은 SAML 전송자 인증을 위한 클라이언트 및 제공자 바인딩 구성에 대해 읽어 보십시오.
  6. 웹 서비스 제공자 SSL 구성 속성인 clientAuthentication이 X.509 클라이언트 인증서 인증을 요구할 수 있도록 하십시오.
    clientAuthentication 속성은 SSL 클라이언트 인증이 필수인지를 판별합니다. clientAuthentication 속성을 지정하려면 관리 콘솔을 사용하여 다음 조치를 완료하십시오.
    1. 보안 > SSL 인증서 및 키 관리 > 엔드포인트 보안 구성 관리 > {인바운드 | 아웃바운드} > SSL_configuration을 클릭하십시오.
    2. WC_defaulthost_secure 링크를 클릭하십시오.
    3. 관련 항목에서 SSL_configurations 링크를 클릭하십시오.
    4. NodeDefaultSSLSettings 자원을 선택하십시오.
    5. QoP(Quality of protection) 설정 링크를 클릭하십시오.
    6. 클라이언트 인증을 지정하려면 메뉴에서 필수를 선택하십시오.

    clientAuthentication 속성 구성에 대해 자세히 알아보려면 보안 소켓 계층 구성 작성에 대해 읽어 보십시오.

  7. 웹 서비스 클라이언트 코드에서 CallService() 메소드를 사용하여 자체 발행 SAML 토큰을 생성하는 데 필요한 구성 매개변수를 포함하는 특성 파일을 지정하십시오.

    CallService() 메소드는 자체 발행 SAML 토큰을 생성하기 위해 웹 서비스 보안 런타임 환경에 필요한 구성 매개변수를 지정합니다.

    다음 코드 스니펫은 CallService() 메소드를 사용하여 웹 서비스 보안 구성 매개변수를 지정하는 것을 보여줍니다.
    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("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf ");
        // Initialize WSSFactory object 
        WSSFactory factory = WSSFactory.getInstance();
    
        // Initialize WSSGenerationContext
        WSSGenerationContext gencont = factory.newWSSGenerationContext();
        // Initialize SAML issuer configuration via custom properties
        HashMap <Object, Object> customProps = new HashMap<Object,Object>();
    
        customProps.put(SamlConstants.ISSUER_URI_PROP, "example.com");
        customProps.put(SamlConstants.TTL_PROP, "3600000");
        customProps.put(SamlConstants.KS_PATH_PROP, "keystores/saml-provider.jceks");
        customProps.put(SamlConstants.KS_TYPE_PROP, "JCEKS");
        customProps.put(SamlConstants.KS_PW_PROP, "{xor}LCswLTovPiws");
        customProps.put(SamlConstants.KEY_ALIAS_PROP, "samlissuer");
        customProps.put(SamlConstants.KEY_NAME_PROP, "CN=SAMLIssuer, O=EXAMPLE");
        customProps.put(SamlConstants.KEY_PW_PROP, "{xor}NDomLz4sLA==");
        customProps.put(SamlConstants.TS_PATH_PROP, "keystores/saml-provider.jceks");
        customProps.put(SamlConstants.TS_TYPE_PROP, "JCEKS");
        customProps.put(SamlConstants.TS_PW_PROP, "{xor}LCswLTovPiws");  
        gencont.add(customProps); //Add custom properties

    토큰 구성 방식을 제어하기 위한 구성 특성을 지정하는 방식에 대한 자세한 정보는 토큰 작성 중 SAML 토큰 구성에 대해 읽어 보십시오.

  8. 클래스 경로에 JAX-WS JAR 파일의 씬 클라이언트를 추가하십시오. app_server_root/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar 파일을 클래스 경로에 추가하십시오. 이 JAR 파일을 클래스 경로에 추가하는 것에 대한 자세한 정보는 웹 서비스 사용 클라이언트 테스트 정보를 참조하십시오.
  9. 자체 발행 SAML 토큰을 작성하십시오. 다음 코드 스니펫은 SAML 전송자 인증 토큰을 작성하는 것을 보여줍니다.
    // Create SAMLToken
    HashMap<Object, Object> map = new HashMap<Object, Object>();
    map.put(SamlConstants.CONFIRMATION_METHOD, "sender-vouches");
    map.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML20_VALUE_TYPE);
    map.put(SamlConstants.SAML_NAME_IDENTIFIER, "Alice");
    map.put(SamlConstants.SIGNATURE_REQUIRED, "true");			
    SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map);	
    SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml");
    System.out.println("SAMLToken id = " + samlToken.getId());
    1. WSSFactory newSecurityToken 메소드를 사용하여 SAML 토큰을 작성하는 방법을 지정하십시오.
      다음 메소드를 지정하여 SAML 토큰을 작성하십시오.
      WSSFactory  newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml")
      SAML 토큰을 작성하려면 Java 보안 권한 permission wssapi.SAMLTokenFactory.newSAMLToken이 필요합니다. 정책 도구를 사용하여 다음 정책 명령문을 Java 보안 정책 파일 또는 애플리케이션 클라이언트 was.policy 파일에 추가하십시오.
      permission java.security.SecurityPermission "wssapi.SAMLTokenFactory.newSAMLToken

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

      callbackHandler 오브젝트는 작성하고 있는 SAMLToken의 특성을 정의하는 매개변수를 포함합니다. 이 오브젝트는 다음 테이블에 설명되어 있는 구성 매개변수를 지정하는 SAMLGenerateCallbackHandler 오브젝트를 가리킵니다.
      표 1. SAMLGenerateCallbackHandler 특성. 이 테이블은 전송자 인증 확인 메소드를 사용하는 SAMLGenerateCallbackHandler 오브젝트의 구성 매개변수를 설명합니다.
      특성 설명 Required
      SamlConstants.CONFIRMATION_METHOD sender-vouches 확인 메소드를 사용하도록 지정합니다.
      SamlConstants.TOKEN_TYPE

      상수 값 WSSConstants.SAML.SAML20_VALUE_TYPE을 사용하여 SAML 2.0 토큰 유형을 지정합니다.

      웹 서비스 클라이언트에 정책 세트 첨부가 있는 경우 이 특성은 웹 서비스 보안 런타임 환경에서 사용되지 않습니다. 이 시나리오에서 tokenGenerator 바인딩 구성의 valueType 속성을 사용하여 토큰 값 유형을 지정하십시오.

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

      SamlConstants.SAML_NAME_IDENTIFIER

      SAML 토큰의 NameID 값으로 myname과 같은 사용자 ID를 지정합니다.

      JAX-WS의 씬 클라이언트를 사용할 때 이 매개변수를 정의하지 않으면 NameID 값에 유용한 정보가 포함되지 않습니다.

      웹 서비스 요청 호출을 작성하는 Java EE(Java Platform, Enterprise Edition) 애플리케이션과 같은 웹 서비스 관리 클라이언트를 사용하는 경우 웹 서비스 보안 런타임 환경은 보안 컨텍스트에서 사용자 보안 정보를 추출하려고 합니다. 마찬가지로 관리 웹 서비스 클라이언트에 대해 이 매개변수를 정의하지 않는 경우 NameID 값에 UNAUTHENTICATED 이름 ID가 포함됩니다.

      이 특성은 웹 서비스 클라이언트에 정책 세트 첨부가 있는 경우에 사용되지 않습니다. SAML 토큰 ID 및 속성 전송에 대해 자세히 알아보려면 SAML 토큰 전송에 대해 읽어 보십시오.

      아니오
      SamlConstants.SIGNATURE_REQUIRED

      발행자가 SAML 토큰에 디지털로 서명해야 하는지 여부를 지정합니다.

      true 값은 발행자가 SAML 토큰을 디지털로 서명해야 함을 지정합니다. 이 값이 기본값입니다.

      아니오
      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())

결과

전송 보호와 함께 전송자 인증 확인 메소드로 자체 발행 SAML 토큰을 작성한 다음 JAX-WS 프로그래밍 모델 및 WSS API를 사용하여 웹 서비스 요청 메시지와 함께 이 토큰을 전송했습니다.

다음 코드 샘플은 자체 발행 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.wssapi.WSSFactory;
import com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext;
import com.ibm.websphere.wssecurity.wssapi.WSSConsumingContext;
import com.ibm.websphere.wssecurity.wssapi.WSSTimestamp;
import com.ibm.websphere.wssecurity.callbackhandler.SAMLGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.saml.config.SamlConstants;

import java.util.Map;
import java.util.HashMap;

import javax.xml.ws.BindingProvider;

public class SampleSamlSVClient {
  private String urlHost = "localhost";
  private String urlPort = "9081";
  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("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf ");

      // Initialize WSSFactory object
      WSSFactory factory = WSSFactory.getInstance();
      // Initialize WSSGenerationContext
      WSSGenerationContext gencont = factory.newWSSGenerationContext();
      // Initialize SAML issuer configuration via custom properties
	    HashMap<Object, Object> customProps = new HashMap<Object,Object>();

      customProps.put(SamlConstants.ISSUER_URI_PROP, "example.com");
      customProps.put(SamlConstants.TTL_PROP, "3600000");
      customProps.put(SamlConstants.KS_PATH_PROP, "keystores/saml-provider.jceks");
      customProps.put(SamlConstants.KS_TYPE_PROP, "JCEKS");
      customProps.put(SamlConstants.KS_PW_PROP, "{xor}LCswLTovPiws");
      customProps.put(SamlConstants.KEY_ALIAS_PROP, "samlissuer");
      customProps.put(SamlConstants.KEY_NAME_PROP, "CN=SAMLIssuer, O=EXAMPLE");
      customProps.put(SamlConstants.KEY_PW_PROP, "{xor}NDomLz4sLA==");
      customProps.put(SamlConstants.TS_PATH_PROP, "keystores/saml-provider.jceks");
      customProps.put(SamlConstants.TS_TYPE_PROP, "JCEKS");
      customProps.put(SamlConstants.TS_PW_PROP, "{xor}LCswLTovPiws");  
      gencont.add(customProps); //Add custom properties

      // Create SAMLToken
      HashMap<Object, Object> map = new HashMap<Object, Object>();
      map.put(SamlConstants.CONFIRMATION_METHOD, "sender-vouches");
      map.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML20_VALUE_TYPE);
      map.put(SamlConstants.SAML_NAME_IDENTIFIER, "Alice");
      map.put(SamlConstants.SIGNATURE_REQUIRED, "true");			
      SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map);
      SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, callbackHandler, "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");

      gencont.add(samlToken);

      // Add timestamp
      WSSTimestamp timestamp = factory.newWSSTimestamp();
      gencont.add(timestamp);

      gencont.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);

      // Prepare to consume timestamp in response message
      WSSConsumingContext concont = factory.newWSSConsumingContext();
      concont.add(WSSConsumingContext.TIMESTAMP);
      concont.process(requestContext);

      // 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_transportlevel_usingwssapi
파일 이름:twbs_configsamlsendervouches_transportlevel_usingwssapi.html