SAML 令牌库 API
您可以将 SAML 令牌库应用程序编程接口 (API) 提供的方法用于创建、验证、解析和提取 SAML 令牌。
概述
SAML V1.1 和 SAML V2.0 的库实施提供三种类型的主体集:holder-of-key (HoK)、bearer 和 sender-vouches。您可以使用 SAML 令牌库 API 来创建、验证和抽取 SAML HoK 或 bearer 令牌的属性。还讨论来自 Web service SOAP 消息的 SAML 令牌传播。提供样本代码来演示对 API 的使用。
SAML 的 WebSphere® Application Server 提供缺省策略集来支持 bearer 和 HoK 主体集确认。
WSS API SAML 支持对 com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory 和 com.ibm.websphere.wssecurity.wssapi.trust.WSSTrustClient 接口进行了补充。使用 com.ibm.websphere.wssecurity.wssapi.WSSFactory newSecurityToken() 方法生成的 SAMLToken 可以由 SAMLTokenFactory 和 WSSTrustClient 编程接口处理。相反,由 SAMLTokenFactory 生成或由 WSSTrustClient 返回的 SAMLToken 可以用在 WSS API 中。确定要在应用程序中使用哪个 API 取决于您的具体需求。就 Web service 客户机应用程序而言,WSS API SAML 支持可提供与 SAMLTokenFactory 和 WSSTrustClient 接口同等的功能,在这种意义上,该支持是完备的。SAMLTokenFactory 接口具有更多功能,可验证 SAMLToken 以及创建表示已认证 SAMLToken 的 JAAS 主体。此验证对于 Web service 提供者端十分有用。当您开发应用程序以处理 SAMLToken 时,SAMLTokenFactory 编程接口更适合您。
令牌创建参数的配置
您配置令牌创建参数时,配置信息与请求实体、发布实体或接收实体相关。在此示例中,为请求和发布实体定义配置信息。对于每种类型的受支持主体集确认,SAML 令牌库为请求实体提供预配置属性。在 WebSphere 运行时环境创建自签发 SAML 令牌期间,使用这些属性。自签发 SAML 令牌是在本地生成的令牌,而不是从安全性令牌服务 (STS) 请求的令牌。 如果您需要定制缺省参数的属性,请使用 RequesterConfig 参数。有关更多信息,请参阅 SAMLTokenFactory API 主题中关于 RequesterConfig 参数的信息。
// Setup the requester's configuration information (parameters needed
// to create the token specified as configuration properties).
// in this case we are using the configuration information to create a
// SAML token that contains a symmetric holder of key subject
// confirmation.
RequesterConfig requesterData =
samlFactory.newSymmetricHolderOfKeyTokenGenerateConfig();
// Set recipient's public key alias
// (in this example we use SOAPRecipient), so the provider can encrypt secret
// key for the receiving end.
requesterData.setKeyAliasForAppliesTo("SOAPRecipient");
// Set the authentication method that took place. This is an optional
// parameter. reqData.setAuthenticationMethod("Password");
// Set issuer information by instantiating a default ProviderConfig.
// See javadocs for the SAMLTokenFactory class on the details of the
// default values and how to modify them.
ProviderConfig samlIssuerCfg =
samlFactory.newDefaultProviderConfig("WebSphereSelfIssuer");
创建 SAML 令牌工厂实例
指定 SAML 令牌类型(V1.1 或 V2.0)来使用 SAMLTokenFactory 类。为创建 SAML 令牌设置其他参数。// Instantiate a token factory based on the version level of the token
// to use. In this example we use the SAML v1.1 token factory.
SAMLTokenFactory samlFactory =
SAMLTokenFactory.getInstance(SAMLTokenFactory.WssSamlV11Token11);
// Retrieve the caller subject or the runAsSubject (depending on your
// scenario) then use the Subject to get a CredentialConfig object
// using the SAML token library.
// This invocation requires the
// wssapi.SAMLTokenFactory.newCredentialConfig" Java Security
// permission.
CredentialConfig cred = samlFactory.newCredentialConfig(runAsSubject);
创建 SAML 令牌
// Now create the SAML token. This invocation requires the
// "wssapi.SAMLTokenFactory.newSAMLToken" Java Security permission.
SecurityToken samlToken =
samlFactory.newSAMLToken(cred, reqData, samlIssuerCfg);
SAML 令牌验证
接收 SAML 令牌的实体(例如业务服务)可以使用 SAML 令牌库 API 来验证令牌,然后予以使用。例如,服务需要验证令牌,然后从请求者抽取 SAML 属性。可以使用来自使用者的配置数据来验证现有 SAML 断言文档。ConsumerConfig consumerConfig = samlFactory.newConsumerConfig();
XMLStructure xml =
try {
SAMLToken token = samlFactory.newSAMLToken( consumerConfig, XMLStructure xml );
// token successfully validated
} catch(WSSException e) {
// token failed validation
}
映射到主体集的 SAML 令牌身份
SAML 令牌可用于创建主体集。SAML 令牌中的名称标识映射到用户注册表中的用户以获取主体集的主体名称。Subject subject;
SAMLToken aSAMLToken = ...;
try {
subject = samlFactory.newSubject(aSAMLToken);
} catch(WSSException e) {
}
解析断言元素
SAML 令牌的接收方可以使用包含在 SAML 令牌库 API 中的 SAMLToken API 从 SAML 令牌解析和抽取断言元素。例如,可以使用此代码抽取令牌创建时间:Date dateCreated = samlToken.getSamlCreated();
String confirmationMethpo = samlToken.getConfirmationMethod();
String issuerName = samlToken.getSAMLIssuerName();
byte[] hokBytes = samlToken.getHolderOfKeyBytes();
有关所有 SAML API 的更多信息,请参阅 SAMLToken 接口的 API 文档。
SAML 令牌属性抽取
使用 SAMLToken API 从发起实体(服务请求者)抽取 SAML 属性,如以下代码片段中所示。// Get all attributes
List<SAMLAttribute> allAttributes =
((SAMLToken) samlToken).getSAMLAttributes();
// Iterate over the attribute and process accordingly
Iterator<SAMLAttribute> iter = allAttributes.iterator();
while(iter.hasNext())
{
SAMLAttribute anAttribute = iter.next();
// Handle attributes
String attributeName = anAttribute.getName();
String[] attributeValues = anAttribute.getStringAttributeValue();
}
样本代码
样本代码演示如何使用 SAML 令牌库 API 来完成前述的某些操作。指向 SAML 属性文件的位置的 JVM 属性是运行此代码的先决条件。 SAML 属性文件 SAMLIssuerConfig.properties 必须包含关于 SAML 令牌的签发者(提供程序)的配置属性。单元级别的 SAMLIssuerConfig.properties 文件的缺省位置是:app_server_root/profiles/$PROFILE/config/cells/$CELLNAME/sts。
对于服务器级别,缺省位置是:app_server_root/profiles/$PROFILE/config/cells/$CELLNAME/nodes/$NODENAME/servers/$SERVERNAME。
IssuerURI=WebSphere
TimeToLive=3600000
KeyStorePath=c:/samlsample/saml-provider.jceks
KeyStoreType=jceks
KeyStorePassword=myissuerstorepass
KeyAlias=samlissuer
KeyName=CN=SAMLIssuer, O=IBM, C=US
KeyPassword=xxxxxxxxx
TrustStorePath=c:/samlsample/saml-provider.jceks
TrustStoreType=jceks
TrustStorePassword=yyyyyyyy
package samlsample;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
import javax.security.auth.Subject;
// Import methods from the SAML token library
import com.ibm.wsspi.wssecurity.saml.data.SAMLAttribute;
import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
import com.ibm.wsspi.wssecurity.saml.config.ProviderConfig;
import com.ibm.wsspi.wssecurity.saml.config.RequesterConfig;
import com.ibm.wsspi.wssecurity.saml.config.CredentialConfig;
import com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.wsspi.wssecurity.core.token.config.RequesterConfiguration;
public class SamlAPIsample {
public void testSAMLTokenLibrary() throws Exception {
try {
// Get an instance of the SAML v1.1 token factory
SAMLTokenFactory samlFactory = SAMLTokenFac
tory.getInstance(SAMLTokenFactory.WssSamlV11Token11);
// Generate default requester data for a subject confirmation of
// type holder-of-key (secret key).
RequesterConfig requesterData =
samlFactory.newSymmetricHolderOfKeyTokenGenerateConfig();
// Set the recipient's key alias, so that the issuer can encrypt
// the secret key for recipient as part of the subject confirmation.
requesterData.setKeyAliasForAppliesTo("SOAPRecipient");
// Set the authentication method that took place. requesterData.setAuthenticationMethod("Password");
System.out.println("default holder of key confirmation key type is: "+
Requester
Data.getRSTTProperties().get(RequesterConfiguration.RSTT.KEYTYPE));
Requester
Data.getRSTTProperties().put(RequesterConfiguration.RSTT.KEYTYPE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey");
requesterData.getRSTTProperties().put(
RequesterConfiguration.RSTT.APPLIESTO_ADDRESS,
"http://localhost:9080");
requesterData.setConfirmationMethod("holder-of-key");
// Set the recipient's key alias so that token infomation such as
// the secret HoK can be encrypted by the issuer and decrypted by the
// recipient.
requesterData.setKeyAliasForAppliesTo("SOAPRecipient");
requesterData.setAuthenticationMethod("Password");
requesterData.getRSTTProperties().put(
RequesterConfiguration.RSTT.ENCRYPTIONALGORITHM,
"http://www.w3.org/2001/04/xmlenc#aes128-cbc");
requester
Data.getRSTTProperties().put(RequesterConfiguration.RSTT.TOKENTYPE,
"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-
1.1#SAMLV1.1");
requesterData.setRequesterIPAddress("9.53.52.65");
// Print requester configuration items
System.out.println("authentication method for requester is: "+
requesterData.getAuthenticationMethod());
System.out.println("confirmation method for requester is: "+
requesterData.getConfirmationMethod());
System.out.println("key alias for requester is: "+
requesterData.getKeyAliasForRequester());
System.out.println("key alias for recipient as set in requester config is "+
requesterData.getKeyAliasForAppliesTo());
System.out.println("holder of key confirmation key type is: "+
Requester
Data.getRSTTProperties().get(RequesterConfiguration.RSTT.KEYTYPE));
// Get an instance of the Credential config object
CredentialConfig cred = samlFactory.newCredentialConfig();
cred.setRequesterNameID("Alice");
// Set some user attributes
ArrayList<SAMLAttribute> userAttrs = new ArrayList<SAMLAttribute>();
SAMLAttribute anAttribute = new SAMLAttribute("EmployeeInfo",
new String[] {"GreenRoofing","JohnDoe", "19XY981245"},
null, "WebSphere Namespace", null, "JohnDoeInfo " );
userAttrs.add(anAttribute);
cred.setSAMLAttributes(userAttrs);
// Get default provider configuration
ProviderConfig samlIssuerCfg =
samlFactory.newDefaultProviderConfig("WebSphereSelfIssuer");
System.out.println("time to live from the default provider config: "+
samlIssuerCfg.getTimeToLive());
System.out.println("keyStore path from default provider config: "+
samlIssuerCfg.getKeyStoreConfig().getPath());
System.out.println("keyStore type from default provider config: "+
samlIssuerCfg.getKeyStoreConfig().getType());
System.out.println("key alias from default provider config: "+
samlIssuerCfg.getKeyInformationConfig().getAlias());
// Generate the SAML token
SecurityToken samlToken =
samlFactory.newSAMLToken(cred, requesterData, samlIssuerCfg);
System.out.println("token's creation Date is:
"+((SAMLToken)samlToken).getSamlCreated().toString());
System.out.println("token's expiration Date is:
"+((SAMLToken)samlToken).getSamlExpires().toString());
System.out.println("token's subject confirmation method is:
"+((SAMLToken)samlToken).getConfirmationMethod());
// Create a Subject, mapping the name identifier in the token to a user
// in the user registry to obtain the Principal name
Subject subject = samlFactory.newSubject((SAMLToken)samlToken);
// Retrieve attributes from the token
List<SAMLAttribute> allAttributes =
((SAMLToken)samlToken).getSAMLAttributes();
// Iterate through the attributes and process accordingly
Iterator<SAMLAttribute> iter = allAttributes.iterator();
while (iter.hasNext()) {
SAMLAttribute attribute = iter.next();
String attributeName = attribute.getName();
String[] attributeValues = attribute.getStringAttributeValue();
System.out.println("attribute name = "+ attributeName +
" attribute value = ["+
attributeValues[0]+ ",
"+attributeValues[1]+ ", "+
attributeValues[2]+"]");
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
样本代码输出
default holder of key confirmation key type is: http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey
authentication method for requester is: Password
confirmation method for requester is: holder-of-key
key alias for requester is: null
key alias for recipient as set in requester config is SOAPRecipient
holder of key confirmation key type is: http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey
time to live from the default provider config: 3600000
keyStore path from default provider config: C:/saml/samlsample/saml-provider.jceks
keyStore type from default provider config: jceks
key alias from default provider config: samlissuer
token's creation Date is: Mon Sep 14 15:49:00 CDT 2009
token's expiration Date is: Mon Sep 14 16:49:00 CDT 2009
token's subject confirmation method is: urn:oasis:names:tc:SAML:1.0:cm:holder-of-key
attribute name = EmployeeInfo attribute value = [GreenRoofing, JohnDoe, 19XY981245]