Request the authentication token from an external STS.
The following code snippet illustrates how to request the authentication
token to be used with WebSphere generic
SecurityToken login module, and assumes that an external STS is configured
to accept a Username token as authentication token, and to issue a
SAML 1.1 token.//Request SecurityToken from external STS:
WSSFactory factory = WSSFactory.getInstance();
//STS URL that issues the requested token
String STS_URI = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
//Web services endpoint that receives the issued token
String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
//Begin sample code 1 (Using WS-Trust Issue to request the token from
//the STS in which authentication token is send over WS-Security head):
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//The following property specifies that the ws-trust request should be
//compliance with WS-Trust 1.3 spec
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//This request is made with WS-TRust Issue only (without the use of
//WS-Trust Validate)
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Create the context object for WS-Trust request:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT for trust request authentication
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//End of sample code 1.
//Begin sample code 2 (using WS-Trust Validate to request a token by
//exchanging a token in RunAs Subject).
//If web service client has RunAs Subject , for example an
//authenticated intermediate server acts as a client to invoke the
//downstream service, you can program the client to use the token from
//the RunAs subject to exchange with the STS by using WS-Trust validate.
//To do so, you replace sample code 1 with the following:
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//This request is made with WS-Trust 1.3
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//add the next line if you do not want to fallback to WS-Trust Issue if
//token exchange fails.
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY, "true");
//add the next line to specify the token type in the RunAs subject that
//will be used to exchange the requested token. For example, you use
//the LTPA token to exchange for a SAML token. If the exchanged token
//in the RunAs subject has the same value type as the requested token,
//setting IssuedTokenConfigConstants.USE_TOKEN is not required.
cbackMap1.put(IssuedTokenConfigConstants.USE_TOKEN, LTPAToken.ValueType);
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//The following codes are added if Authentication token in ws-security
//head or Message level security protection is required. If there is no
//Message level protection or additional authentication token for
//WS-Trust Validate, do not create the context object shown below.
//Context object for WS-Trust request:
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Use UNT for trust request authentication
UNTGenerateCallbackHandler utCallbackHandler =
new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//End of sample code 2.
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
//The following step to set ValueType is required..
//The parameter is always the QName of the requested token's valueType.
//QName for SAML1.1:
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//This article includes QName definitions for SAML11, SAML20, TAM
//token, and Pass ticket token.
//QName for SAML 2.0:
QName Saml20ValueType = new QName(WSSConstants.SAML.SAML20_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//QName for TAM token:
QName TamValueType = new QName("http://ibm.com/2004/01/itfim/ivcred");
//QName for PassTicket token:
QName PassTicketValueType = new QName("http://docs.oasis-open.org/wss/
2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken");
//You can use the Token interface to get the token ValueType QName for
//all other tokens. For example, a Username Token's QName is //UsernameToken.ValueType.
The GenericIssuedTokenGenerateCallbackHandler object
contains parameters that define the characteristics of the security
token that you are requesting, as well as other parameters required
to reach the STS and to obtain the security token. The GenericIssuedTokenGenerateCallbackHandler object
specifies the configuration parameters described in the following
table:
Table 1. GenericIssuedTokenGenerateCallbackHandler properties. This table describes the configuration parameters for the GenericIssuedTokenGenerateCallbackHandler object,
and specifies whether or not the property is required.
Property |
Description |
Required |
IssuedTokenConfigConstants.STS_ADDRESS |
Specifies the http address of the STS. When
communication to the STS is protected with SSL, you must set the -Dcom.ibm.SSL.ConfigURL property.
SSL connection to the STS is indicated with an https:// address
prefix.
|
Yes |
IssuedTokenConfigConstants.APPLIES_TO |
Specifies the target service address for where
you want to use the token. |
No |
IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST |
Specifies whether to request a single token
from the STS that is enclosed in a RequestSecurityToken (RST) element
or multiple tokens in a collection of RST elements that are enclosed
in a single RequestSecurityTokenCollection (RSTC) element.
The default behavior is to request a single token that is enclosed
in a RequestSecurityToken (RST) element from the
STS.
Specifying a true value for this
property indicates a request for multiple tokens in a collection of
RST elements that are enclosed in a single RequestSecurityTokenCollection
(RSTC) element from the STS.
The default value is false.
|
No |
IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE |
Specifies the WS-Trust namespace that is included
in the WS-Trust request. The default value is WSTrust 1.3.
|
No |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT |
Specify if you want WS-Security to use the token
from the RunAs subject to exchange the requested token first by using
WS-Trust Validate. If set to false, WS-Security
will use WS-Trust Issue to request the token. The default value
is true.
|
No |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY |
Specify if you do not want WS-Security to use
WS-Trust Issue to the requested token if token exchange fails. The
default value is false.
|
No |
IssuedTokenConfigConstants.USE_TOKEN |
Use this value to choose a token from the RunAs
subject to exchange the requested token. The default value is the
requested token's ValueType.
|
No |
A WSSGenerationContext instance and a WSSConsumingContext instance
are also set in the GenericIssuedTokenGenerateCallbackHandler object.
In this example, the WSSGenerationContext instance
contains a UNTGenerateCallbackHandler object with
the information to create the UsernameToken that
you want to send to the STS.
The
system.wss.generate.issuedToken parameter
specifies the Java Authentication
and Authorization Service (JAAS) login module that is used to create
the generic security token. You must specify a JVM property to define
a JAAS configuration file that contains the required JAAS login configuration;
for example:
-Djava.security.auth.login.config=profile_root/properties/wsjaas_client.conf
Alternatively,
you can specify a JAAS login configuration file by setting a Java system property in the sample
client code; for example:
System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf");
Add an X.509 token for message protection (skip this step
if the web service is protected with SSL Transport level protection
only). The following sample code uses the dsig-sender.ks key
file and the SOAPRequester sample key. You must not
use the sample key in a production environment. The following code
illustrates adding an X.509 token for message protection://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(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
sig.addSignPart(sigPart);
sig.addSignPart(WSSSignature.BODY);
- Create a WSSSignature object with the
X.509 token. The following line of code creates a WSSSignature object
with the X.509 token:
WSSSignature sig = factory.newWSSSignature(x509);
- Add the signed part to use for message protection.
The following line of code specifies to add WSSSignature.BODY as
the signed part:
sig.addSignPart(WSSSignature.BODY);
- Add the Timestamp element in the SOAP
Security header. The SAML20 SenderVouches WSHTTPS and SAML11
SenderVouches WSHTTPS policy sets require web service requests
and responses to contain a Timestamp element in the
SOAP Security header. In the following code, the WSSFactory.newWSSTimestamp() method
generates a Timestamp element, and the WSSGenerationContext.add(timestamp) method
adds the Timestamp element to the request message:
// Add Timestamp element
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
- Skip this step if token signature is not required. If
the requested security token needs to be signed with the STR
Dereference Transform reference option, follow step 1. Otherwise,
follow step 2. The STR Dereference Transform reference
option is commonly known as STR-Transform.
Step
1: Some tokens, including SAML Tokens, cannot be digitally signed
directly. You must sign the token using STR-Transform.
In order for a token to be signed with STR-Transform,
it must be referenced by a <wsse:SecurityTokenReference> element
in the <wsse:Security> header block. To sign a
security token with STR-Transform, a separate WSSSignPart is
created to specify the SecurityTokenReference with
a transformation algorithm that is represented by the WSSSignPart.TRANSFORM_STRT10 attribute.
This attribute enables the WS-Security runtime environment to generate
a SecurityTokenReference element to reference the
token, and to digitally sign the token using the STR Dereference reference
option. The following code illustrates the use of the WSSSignPart.TRANSFORM_STRT10 attribute:
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
Step
2: If the requested signed token is not a SAML token, or STR-Transform is
not used, use the following code instead:sig.addSignPart(token);
- Attach the WSSGenerationContext object
to the web service RequestContext object. The WSSGenerationContext object
now contains all of the security information required to format a
request message. The WSSGenerationContext.process(requestContext) method
attaches the WSSGenerationContext object to the web
service RequestContext object to enable the WS-Security
runtime environment to format the required SOAP Security header; for
example:
// Attaches the WSSGenerationContext object to the web service RequestContext object.
gencont.process(requestContext);