WSS API를 사용하여 자체 발행 SAML 전달자 토큰 전송

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

시작하기 전에

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

이 태스크 정보

웹 서비스 보안 프로그래밍 인터페이스를 사용하여 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 Bearer WSHTTPS 기본 정책 세트를 웹 서비스 제공자에 첨부하십시오. 이 정책 세트는 HTTPS 전송을 사용하여 메시지를 보호하는 데 사용됩니다. SAML20 Bearer WSHTTPS 기본 정책 세트를 웹 서비스 제공자에 첨부하는 방법에 대한 세부사항은 SAML 전달자 토큰에 대한 클라이언트 및 제공자 바인딩에 대해 읽어 보십시오. 이 프로시저의 예에서는 자체 발행 SAML 토큰을 사용합니다. 제공자 바인딩을 구성할 때 신뢰 저장소 구성 및 인증서는 자체 발행 토큰의 서명 키와 일치해야 합니다.
  3. SAML 전달자 제공자 샘플 기본 일반 바인딩을 샘플 웹 서비스 제공자에 지정하십시오. SAML 전달자 제공자 샘플 기본 일반 바인딩을 웹 서비스 애플리케이션에 지정하는 것에 대한 세부사항은 SAML 전달자 토큰에 대한 클라이언트 및 제공자 바인딩 구성에 대해 읽어 보십시오.
  4. 자체 발행 SAML 토큰을 작성하십시오. 다음 코드 스니펫은 SAML 토큰을 작성하는 것을 보여줍니다.
    // Create the SAML token.
    HashMap<Object, Object> map = new HashMap<Object, Object>();
    map.put(SamlConstants.CONFIRMATION_METHOD, "Bearer");
    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);				            
    callbackHandler.setWSSGenerationContextForTrustClient(gencont);
    SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml");
    
    System.out.println("SAMLToken id = " + samlToken.getId());
    1. CallService() 메소드를 사용하여 자체 발행 SAML 토큰을 사용하는 대상 웹 서비스 제공자를 호출하는 데 필요한 웹 서비스 보안 구성 매개변수를 지정하십시오.

      CallService() 메소드는 자체 발행 SAML 토큰을 생성하기 위한 com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext 사용자 정의 특성을 통해 웹 서비스 보안 런타임 환경에 필요한 구성 매개변수를 설정합니다.

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

    2. 클래스 경로에 JAX-WS JAR 파일의 씬 클라이언트를 추가하십시오. app_server_root/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar 파일을 클래스 경로에 추가하십시오. 이 JAR 파일을 클래스 경로에 추가하는 것에 대한 자세한 정보는 웹 서비스 사용 클라이언트 테스트 정보를 참조하십시오.
    3. 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 Bearer 확인 메소드를 사용하도록 지정합니다.
      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 ");
    4. 작성된 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");
      			
    2. WSSGenerationContext를 초기화하십시오. 다음 코드는 생성 컨텍스트를 초기화하고 사용자가 SAMLToken을 웹 서비스 요청 메시지로 삽입할 수 있도록 하기 위해 WSSGenerationContext 인터페이스를 사용하는 것에 대해 보여줍니다.
      // Initialize WSSGenerationContext
      WSSGenerationContext gencont = factory.newWSSGenerationContext();
      gencont.add(samlToken);	
      특히 gencont.add(samlToken) 메소드 호출은 SAML 토큰을 요청 메시지에 넣도록 지정합니다. 정책 도구를 사용하여 다음 정책 명령문을 Java 보안 정책 파일 또는 애플리케이션 클라이언트 was.policy 파일에 추가하십시오.
       “permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
    3. SOAP 메시지 보안 헤더에 시간소인 요소를 추가하십시오. SAML20 전달자 WSHTTPS 기본 정책 세트에는 웹 서비스 요청 및 SOAP 메시지 보안 헤더에 시간소인 요소를 담고 있는 응답 메시지가 필요합니다. 다음 코드 스니펫에서 factory.newWSSTimestamp() 메소드 호출은 시간소인을 생성하고 gencont.add(timestamp) 메소드 호출은 요청 메시지에 넣을 시간소인을 지정합니다.
      // Add a timestamp to the request message. 
      WSSTimestamp timestamp = factory.newWSSTimestamp();
      gencont.add(timestamp);
      	        
      gencont.process(requestContext);
    4. WSSGenerationContext 오브젝트를 웹 서비스 RequestContext 오브젝트에 첨부하십시오. WSSGenerationContext 오브젝트에는 이제 요청 메시지를 형식화하는 데 필요한 모든 보안 정보가 들어 있습니다. gencont.process(requestContext) 메소드 호출은 WSSGenerationContext 오브젝트를 웹 서비스 RequestContext 오브젝트에 첨부하여 웹 서비스 보안 런타임 환경이 필요한 SOAP 보안 헤더를 형식화할 수 있도록 합니다. 예를 들면, 다음과 같습니다.
      // Attaches WSSGenerationContext object to the web services RequestContext object. 
      gencont.process(requestContext);
    5. JVM 특성을 사용하여 SSL 전송 레벨 메시지 보호를 지정하십시오.
      SAML20 전달자 WSHTTPS 기본 정책 세트에는 SSL을 사용하는 전송 레벨 메시지 보호가 필요합니다. 다음 JVM 특성을 사용하여 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");

결과

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

다음 코드 샘플은 자체 발행 SAML 토큰을 작성하고 작성한 SAML 토큰을 웹 서비스 요청 메시지로 전송하는 웹 서비스 클라이언트 애플리케이션입니다. 사용 시나리오에서 SAML 토큰을 필요로 하지만 애플리케이션이 웹 서비스 메시지를 사용하여 SAML 토큰을 전달하지 않아도 되는 경우 다음 샘플 코드의 첫 번째 파트인 // Initialize web services client 섹션까지만 사용하면 됩니다.

/**
 * 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;

/**
 * SampleClient
 * main entry point for thin client JAR sample
 * and worker class to communicate with the services
 */
public class SampleClient {

  private String urlHost = "localhost";
  private String urlPort = "9443";
  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()
   * 
   * see printusage() for command-line arguments
   * 
   * @param args
   */
  public static void main(String[] args) {
    SampleClient sample = new SampleClient();
    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 ");
      System.setProperty("com.ibm.SSL.ConfigURL", "file:profile_root/properties/ssl.client.props");

      // 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, "Bearer");
      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 = _191EBC44865015D9AB1270745072344
Retrieving document at 'file:profile_root/.../wsdl/'.
>> CLIENT: SEI Echo to https://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_configsamlbearer_usingwssapi
파일 이름:twbs_configsamlbearer_usingwssapi.html