Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
stsProperties.setEncryptionCrypto(crypto);
stsProperties.setSignatureCrypto(crypto);
stsProperties.setEncryptionUsername("myservicekey");
stsProperties.setSignatureUsername("mystskey");
stsProperties.setCallbackHandler(new PasswordCallbackHandler());
stsProperties.setIssuer("STS");
issueOperation.setStsProperties(stsProperties);
// Mock up a request
RequestSecurityTokenType request = new RequestSecurityTokenType();
JAXBElement<String> tokenType =
new JAXBElement<String>(
QNameConstants.TOKEN_TYPE, String.class, WSConstants.WSS_SAML2_TOKEN_TYPE
);
request.getAny().add(tokenType);
JAXBElement<String> keyType =
new JAXBElement<String>(
QNameConstants.KEY_TYPE, String.class, STSConstants.SYMMETRIC_KEY_KEYTYPE
);
request.getAny().add(keyType);
request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
// Mock up message context
MessageImpl msg = new MessageImpl();
WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
msgCtx.put(
SecurityContext.class.getName(),
createSecurityContext(new CustomTokenPrincipal("alice"))
);
WebServiceContextImpl webServiceContext = new WebServiceContextImpl(msgCtx);
// Now add Entropy
WSSecEncryptedKey builder = new WSSecEncryptedKey();
builder.setUserInfo("mystskey");
builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOEP);
Document doc = DOMUtils.createDocument();
builder.prepare(doc, stsProperties.getSignatureCrypto());
Element encryptedKeyElement = builder.getEncryptedKeyElement();
byte[] secret = builder.getEphemeralKey();
EntropyType entropyType = new EntropyType();
entropyType.getAny().add(encryptedKeyElement);
JAXBElement<EntropyType> entropyJaxbType =
new JAXBElement<EntropyType>(QNameConstants.ENTROPY, EntropyType.class, entropyType);
request.getAny().add(entropyJaxbType);
RequestSecurityTokenResponseCollectionType response =
issueOperation.issue(request, webServiceContext);
List<RequestSecurityTokenResponseType> securityTokenResponse =
response.getRequestSecurityTokenResponse();
assertTrue(!securityTokenResponse.isEmpty());
// Test the generated token.
Element assertion = null;
for (Object tokenObject : securityTokenResponse.get(0).getAny()) {
if (tokenObject instanceof JAXBElement<?>
&& REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
RequestedSecurityTokenType rstType =
(RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
assertion = (Element)rstType.getAny();
}
}
assertNotNull(assertion);
String tokenString = DOM2Writer.nodeToString(assertion);
assertTrue(tokenString.contains("AttributeStatement"));
assertTrue(tokenString.contains("alice"));
assertFalse(tokenString.contains(SAML2Constants.CONF_BEARER));
assertTrue(tokenString.contains(SAML2Constants.CONF_HOLDER_KEY));
// Test that the (encrypted) secret sent in Entropy was used in the SAML Subject KeyInfo
AssertionWrapper assertionWrapper = new AssertionWrapper(assertion);
RequestData data = new RequestData();
Properties properties = new Properties();
properties.put(
"org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin"
);
properties.put("org.apache.ws.security.crypto.merlin.keystore.password", "sspass");
properties.put("org.apache.ws.security.crypto.merlin.keystore.file", "servicestore.jks");
data.setDecCrypto(CryptoFactory.getInstance(properties));
data.setCallbackHandler(new PasswordCallbackHandler());
data.setWssConfig(WSSConfig.getNewInstance());
assertionWrapper.parseHOKSubject(data, new WSDocInfo(assertion.getOwnerDocument()));
SAMLKeyInfo samlKeyInfo = assertionWrapper.getSubjectKeyInfo();
assertTrue(Arrays.equals(secret, samlKeyInfo.getSecret()));