스택된 JAAS 로그인 모듈을 사용한 SAML 토큰 생성 및 이용

GenericSecurityTokenFactory API를 사용하여 작성한 SAML 토큰을 SAMLGenerateLoginModule 또는 GenericIssuedTokenGenerateLoginModule 모듈에 전달할 수 있습니다. 또한 이러한 API를 사용하여 SAMLConsumeLoginModule 또는 GenericIssuedTokenConsumeLoginModule 모듈이 이용하는 SAML 토큰을 얻을 수 있습니다.

시작하기 전에

새 JAAS 로그인 모듈 클래스를 추가할 수 있는 JAX-WS 서비스 클라이언트와 제공자 애플리케이션의 작동하는 세트가 있어야 합니다.

이 태스크 정보

이 태스크는 SAML 1.1 전달자 토큰을 생성하지만 이 토큰은 전송자 인증 및 런타임 환경에서 지원되는 임의의 SAML 버전을 사용하기 위해 쉽게 수정할 수 있습니다.

해당 클래스에 의해 작성된 SAML 토큰을 검사하기 위해 로그인 모듈을 SAMLGenerateLoginModule 아래 스택할 수는 있지만 이러한 방식으로 얻은 SAML 토큰이 디지털 서명을 포함하는 경우 수정할 수 없습니다. 디지털 서명을 포함하는 SAML 토큰을 수정할 경우 이 SAML 토큰에 대한 XML은 업데이트 시 조정되지만 업데이트 전에 이 토큰에 서명했기 때문에 수신자에서 서명 유효성 검증에 실패합니다.

이 태스크는 SAML 1.1 전달자 토큰을 생성하지만 런타임 환경에서 지원되는 모든 SAML 버전 및 유형을 사용할 수 있습니다. GenericSecurityTokenFactory API를 사용한 SAML 토큰 작성 및 수정에 대한 자세한 정보는 SAML 애플리케이션 개발을 참조하십시오. JAAS 로그인 모듈을 사용하는 대신 토큰을 클라이언트의 요청 컨텍스트에 배치하는 방법에 대한 자세한 정보는 com.ibm.wsspi.wssecurity.core.Constants에서 com.ibm.wsspi.wssecurity.token.tokenHolder 및 com.ibm.wsspi.wssecurity.token.enableCaptureTokenContext 상수를 참조하십시오.

생성기 예는 HoK(holder-of-key)를 사용하도록 쉽게 수정할 수 없기 때문에 SAML HoK(holder-of-key)에 특정한 createSamlToken() 메소드의 예가 이 태스크 끝 부분에 제공됩니다.

프로시저

  1. 다음 생성기 JAAS 로그인 모듈을 작성하고 사용자의 애플리케이션 코드에 맞게 수정하여 사용하십시오.
    package test.tokens;
    
    import java.util.ArrayList;
    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 com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory;
    import com.ibm.wsspi.wssecurity.saml.config.CredentialConfig;
    import com.ibm.wsspi.wssecurity.saml.config.ProviderConfig;
    import com.ibm.wsspi.wssecurity.saml.config.RequesterConfig;
    import com.ibm.wsspi.wssecurity.saml.data.SAMLAttribute;
    import com.ibm.wsspi.wssecurity.core.config.KeyInformationConfig;
    import com.ibm.wsspi.wssecurity.core.config.KeyStoreConfig;
    import com.ibm.websphere.wssecurity.wssapi.WSSUtilFactory;
    
    public class MySamlGenerator 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");
        }
        SAMLToken myToken = null;
        try {
          myToken = createSamlToken();
        } 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 SAMLToken createSamlToken() throws Exception {
        //SAML Bearer example 
        SAMLTokenFactory samlFactory = SAMLTokenFactory.getInstance(SAMLTokenFactory.WssSamlV11Token11);
        RequesterConfig reqData = samlFactory.newBearerTokenGenerateConfig();
        reqData.setAuthenticationMethod("Password"); //Authentication method for Assertion
    
        ProviderConfig samlIssuerCfg = samlFactory.newDefaultProviderConfig("self-issue");
    
        CredentialConfig cred = samlFactory.newCredentialConfig ();
        cred.setRequesterNameID("Alice");   // SAML NameIdentifier
    	  
        //Add some SAML attributes:	
        SAMLAttribute attribute = new SAMLAttribute
          ("email", new String[] {"joe@websphere"},null, "WebSphere", "email", "joe");
        ArrayList<SAMLAttribute> al = new ArrayList<SAMLAttribute>();
        al.add(attribute);
        attribute = new SAMLAttribute("Membership", 
          new String[] {"Super users", "My team"}, null, null, null, null  );
        al.add(attribute);
        cred.setSAMLAttributes(al);
    
        SAMLToken samlToken = samlFactory.newSAMLToken(cred, reqData, samlIssuerCfg);
    
        return samlToken;
      }
    
      public boolean logout() throws LoginException {
        return false;
      } 
      public boolean abort() throws LoginException {
        return false;
      }
      public boolean commit() throws LoginException {
        return true;
      }
    }
  2. 다음 이용자 JAAS 로그인 모듈을 작성하고 자신의 애플리케이션 코드에 맞게 수정하여 사용하십시오.
    package test.tokens;
    
    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.namespace.QName;
    import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
    
    public class MySamlConsumer 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");
        }
        //Get the token that was consumed by the GenericIssuedConsumeLoginModule
        SecurityToken myToken = factory.getConsumerTokenFromSharedState(_sharedState, new QName(SAMLTokenFactory.WssSamlV11Token11));
        if (myToken == null) {
            throw new LoginException("myToken is null");
        }
        if (myToken instanceof SAMLToken) {
        	//Examine the SAML token with SAML APIs
        	SAMLToken samlToken = (SAMLToken)myToken;
        	String id = samlToken.getSamlID();
        	String subjectDns = samlToken.getSubjectDNS();
        	//...    	
                } else {
        	throw new LoginException("Did not receive a SAML token");
        }
        return true;
      }
      public boolean logout() throws LoginException {
        return false;
      } 
      public boolean abort() throws LoginException {
        return false;
      }
      public boolean commit() throws LoginException {
        return true;
      }
    }
  3. JAAS 로그인 구성을 작성하십시오.
    1. 관리 콘솔에서 보안 > 글로벌 보안으로 이동하십시오.
    2. 인증 아래에서 JAAS(Java Authentication and Authorization Service) > 시스템 로그인으로 이동하십시오.
    3. SAML 토큰 생성기를 작성하십시오.
      1. 새로 작성을 클릭하고 별명에 test.generate.saml을 입력하십시오.
      2. JAAS 로그인 모듈에서 새로 작성을 클릭하고 모듈 클래스 이름에 test.tokens.MySamlGenerator를 입력하십시오. 로그인 모듈 프록시 사용을 선택하고 확인을 클릭하십시오.
      3. 새로 작성을 클릭하고 모듈 클래스 이름에 com.ibm.ws.wssecurity.wssapi.token.impl.SAMLGenerateLoginModule을 입력하십시오. 확인을 클릭하십시오.
    4. SAML 토큰 이용자를 작성하십시오.
      1. JAAS 시스템 로그인 페이지로 돌아가려면 이동 경로에서 JAAS - 시스템 로그인을 클릭하십시오.
      2. 새로 작성을 클릭하고 별명에 test.consume.saml을 입력하십시오.
      3. JAAS 로그인 모듈에서 새로 작성을 클릭하고 모듈 클래스 이름에 com.ibm.ws.wssecurity.wssapi.token.impl.SAMLConsumeLoginModule을 입력하십시오. 로그인 모듈 프록시 사용을 선택하고 확인을 클릭하십시오.
      4. 저장을 클릭하십시오.
  4. 새 JAAS 로그인 구성을 사용하도록 SAML 토큰 생성기를 구성하십시오.
    1. 관리 콘솔에서 변경하려는 바인딩 구성을 여십시오.
    2. WS-Security > 인증 및 보호를 선택하십시오.
    3. 인증 토큰에서 변경할 SAML 아웃바운드 토큰을 선택하십시오.
    4. JAAS 로그인에서 test.generate.saml을 선택하십시오.
  5. 새 JAAS 로그인 구성을 사용하도록 SAML 토큰 이용자를 구성하십시오.
    1. 관리 콘솔에서 변경하려는 바인딩 구성을 여십시오.
    2. WS-Security > 인증 및 보호를 선택하십시오.
    3. 인증 토큰에서 변경할 SAML 인바운드 토큰을 선택하십시오.
    4. JAAS 로그인에서 test.consume.saml을 선택하십시오.
  6. 저장을 클릭하십시오.
  7. 애플리케이션 서버를 다시 시작하여 JAAS 구성 변경사항을 적용하십시오.
  8. 서비스를 테스트하십시오.

다음 예에서는 createSamlToken() 메소드를 사용하여 비대칭 SAML 2.0 HoK(holder-of-key) 토큰을 작성하는 것을 보여줍니다.
private SAMLToken createSamlToken() throws Exception {
  SAMLTokenFactory samlFactory = SAMLTokenFactory.getInstance(SAMLTokenFactory.WssSamlV20Token11);

  RequesterConfig reqData = samlFactory.newAsymmetricHolderOfKeyTokenGenerateConfig();
  reqData.setAuthenticationMethod("Password");  //Authentication method for Assertion 

  ProviderConfig samlIssuerCfg = samlFactory.newDefaultProviderConfig("self-issue");

  CredentialConfig cred = samlFactory.newCredentialConfig ();
  cred.setRequesterNameID("Alice");   // SAML NameIdentifier

  // (Optional) If you want to use keystore and key properties other than what 
  // is set in the SAMLIssuerConfig.properties file, reset the keystore, 
  // trust store and alias information in the ProviderConfig object.
  KeyInformationConfig kic = samlFactory.newKeyInformationConfig("private_key","keypass","CN=Private");

  KeyStoreConfig ksc = samlFactory.newKeyStoreConfig("jks","/keystores/myKeystore.ks","storepass");

  samlIssuerCfg.setKeyStoreConfig(ksc);    //keystore that holds the private key    
  samlIssuerCfg.setTrustStoreConfig(ksc);  //keystore that holds the public key

  // Set the alias for the public certificate that must exist in the trust store.
  // This alias must not require a password.
  reqData.setKeyAliasForRequester("public_cert");  

  SecurityToken samlToken = samlFactory.newSAMLToken(cred, reqData, samlIssuerCfg);     

  // Get the private key from the key store
  WSSUtilFactory wssufactory = WSSUtilFactory.getInstance();
  java.security.KeyStore ks = wssufactory.getKeyStore("jks","/keystores/myKeystore.ks",
                                                      "storepass".toCharArray());
  java.security.Key privateKey = ks.getKey("private_key", "keypass".toCharArray());

  // Add the private key to the token so that the token can be used to sign 
  // elements in a SOAP message. ((com.ibm.ws.wssecurity.wssapi.token.impl.SecurityTokenImpl)samlToken).
  setKey(SecurityToken.SIGNING_KEY, privateKey);  ((com.ibm.ws.wssecurity.wssapi.token.impl.SecurityTokenImpl)samlToken).
  setKey(SecurityToken.DECRYPTING_KEY, privateKey);

  return samlToken;
}

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



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