use of org.apache.ws.security.handler.WSHandlerResult in project OpenAM by OpenRock.
the class SoapOpenIdConnectTokenProvider method createToken.
@Override
public TokenProviderResponse createToken(TokenProviderParameters tokenProviderParameters) {
try {
final TokenProviderResponse tokenProviderResponse = new TokenProviderResponse();
final SoapTokenProviderBase.AuthenticationContextMapperState mapperState = getAuthenticationContextMapperState(tokenProviderParameters);
String authNContextClassRef;
Set<String> authNMethodsReferences;
final List<WSHandlerResult> securityPolicyBindingTraversalYield = mapperState.getSecurityPolicyBindingTraversalYield();
if (mapperState.isDelegatedContext()) {
final ReceivedToken delegatedToken = mapperState.getDelegatedToken();
authNContextClassRef = authnContextMapper.getAuthnContextForDelegatedToken(securityPolicyBindingTraversalYield, delegatedToken);
authNMethodsReferences = methodsReferencesMapper.getAuthnMethodsReferencesForDelegatedToken(securityPolicyBindingTraversalYield, delegatedToken);
} else {
authNContextClassRef = authnContextMapper.getAuthnContext(securityPolicyBindingTraversalYield);
authNMethodsReferences = methodsReferencesMapper.getAuthnMethodsReferences(securityPolicyBindingTraversalYield);
}
String token;
try {
token = getAssertion(getValidationInvocationContext(tokenProviderParameters), authNContextClassRef, authNMethodsReferences, System.currentTimeMillis() / 1000, NULL_NONCE);
Element tokenElement = buildTokenElement(token);
tokenProviderResponse.setToken(tokenElement);
tokenProviderResponse.setTokenId(getTokenId(token));
return tokenProviderResponse;
} catch (TokenCreationException e) {
throw new AMSTSRuntimeException(e.getCode(), e.getMessage(), e);
}
} finally {
try {
amSessionInvalidator.invalidateAMSessions(threadLocalAMTokenCache.getToBeInvalidatedAMSessionIds());
} catch (Exception e) {
String message = "Exception caught invalidating interim AMSession in SoapOpenIdConnectTokenProvider: " + e;
logger.warn(message, e);
/*
The fact that the interim OpenAM session was not invalidated should not prevent a token from being issued, so
I will not throw a AMSTSRuntimeException
*/
}
}
}
use of org.apache.ws.security.handler.WSHandlerResult in project OpenAM by OpenRock.
the class DefaultSaml2XmlTokenAuthnContextMapper method getWSHandlerResultsDebug.
/*
No toString on WSHandlerResult, so this method will be called to provide debugging information
*/
protected String getWSHandlerResultsDebug(List<WSHandlerResult> handlerResults) {
StringBuilder builder = new StringBuilder();
for (WSHandlerResult result : handlerResults) {
builder.append("WSHandlerResults for actor ").append(result.getActor()).append('\n');
List<WSSecurityEngineResult> securityEngineResults = result.getResults();
if (securityEngineResults != null) {
for (WSSecurityEngineResult securityEngineResult : securityEngineResults) {
builder.append('\t').append(securityEngineResult).append('\n');
}
} else {
builder.append("Null WSSecurityEngineResult list.");
}
}
return builder.toString();
}
use of org.apache.ws.security.handler.WSHandlerResult in project OpenAM by OpenRock.
the class DefaultSaml2XmlTokenAuthnContextMapper method getAuthnContext.
@Override
public String getAuthnContext(List<WSHandlerResult> securityPolicyBindingTraversalYield) {
/*
Note that the code referenced in the forum link above
(https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob_plain;f=services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java;hb=HEAD)
seems to be doing about the same thing (obtaining a token element), but does not do any sanity checking on the
number of handlerResults or engineResults - it just processes and returns the first element. Note that
this seems a bit sloppy, but the AbstractTokenInterceptor subclasses, like org.apache.cxf.ws.security.wss4j.UsernameTokenInterceptor
SamlTokenInterceptor, and KerberosTokenInterceptor insure that the results of processing the token go in the first
element of the WSHandlerResult array, a pattern which the OpenAMSessionTokenServerInterceptor follows. Note that
I get two WSHandlerResult instances when invoked via the am_transport binding, but the OpenAMSessionTokenServerInterceptor
is only invoked once, and only creates a single WSHandlerResult instance - not sure where the other result gets generated, but
it seems to occur as part of timestamp verification, and it pre-exists OpenAMSessionTokenInterceptor#processToken, and includes
both timestamp verification results, and the OpenAM BST. So I will bump the log severity down to debug, as it does not
seem to be an error.
*/
if (securityPolicyBindingTraversalYield != null && securityPolicyBindingTraversalYield.size() > 0) {
final WSHandlerResult handlerResult = securityPolicyBindingTraversalYield.get(0);
if (securityPolicyBindingTraversalYield.size() > 1) {
logger.debug("WSHanderResults obtained from the MessageContext in SoapTokenProviderBase#getAuthnContextClassRef > 1: actual size:" + securityPolicyBindingTraversalYield.size() + "; The results: " + getWSHandlerResultsDebug(securityPolicyBindingTraversalYield));
}
final List<WSSecurityEngineResult> securityEngineResults = handlerResult.getResults();
/*
The List of WSSecurityEngineResult instances is extensive, and is a function of the type of SecurityPolicy binding.
Ultimately, these instances are created by classes in wss4j's org.apache.ws.security.processor package. The set of
SupportingTokens used to traverse the SecurityPolicy bindings in the set of supported .wsdl files is limited to
UsernameTokens, OpenAM Session tokens, and x509 tokens. In both the symmetric and asymmetric bindings, there are
several WSSecurityEngineResult instances which correspond to x509 tokens, as both of these bindings use PKI to
realize confidentiality/integrity of the SupportingTokens/soap-messages. Each WSSecurityEngineResult is constructed
with an action bitmap which specifies the nature of its processing. This action does not seem to differentiate x509
tokens presented as a SupportingToken, and those presented to secure messages and/or presented tokens (in both cases,
the action bitmap appears to be WSConstants.SIGN - see the org.apache.ws.security.processor.SignatureProcessor
for details.). Thus the most reliable scheme will be to traverse all of the WSSecurityEngineResult instances, and look for the presence of a
UsernameToken and a OpenAM Session token. If neither of these tokens are present, then we are dealing with a
x509 SupportingToken.
Listing of WSSecurityEngineResult instances corresponding to various bindings:
For an UNT over the asymmetric binding, the List<WSSecurityEngineResult> has the following elements:
0. action = 2 - WSConstants.SIGN - an x509 certificate, corresponding to the client - the signature of the request
1. action = 1 - WSConstants.UT - the UNT - this is the SupportingToken
2. action = 4 - WSConstants.ENCR - an x509 certificate corresponding to the server cert - public key used to encrypt the message, corresponding to the asymmetric binding
3. action = 32 - WSConstants.TS - timestamp verification
4. action = 4096 - WSConstants.BST - the client’s x509 certificate, used to verify the signature.
For an UNT over the symmetric binding, the List<WSSecurityEngineResult> has the following elements:
0. action = 2 - WSConstants.SIGN - no x509 certificate - signature of the message using the client-generated secret
per the symmetric binding. validated-token = true
1. action = 1 - WSConstants.UT - the UNT - this is the SupportingToken
2. action = 4 - WSConstants.ENCR - no x509 certificate - encryption of the message using the client-generated secret
- validated-token = false
3. action = 2048 - WSConstants.DKT - the derived key - nonce generated by client
4. action = 2048 - WSConstants.DKT - the derived key - key generated by client
5. action = 4 - WSConstants.ENCR - presumably the encryption of the derived key - x509 cert referencing the server's cert
6. action = 32 - WSConstants.TS - timestamp verification
For x509 over the asymmetric binding, the List<WSSecurityEngineResult> has the following elements:
0. action = 2 - WSConstants.SIGN - the client's cert, validated-token = true
1. action = 32 - WSConstants.TS - timestamp verification
2. action = 4096 - WSConstants.BST - the client's X509 certificate, used to verify the signature
For x509 over the symmetric binding, the List<WSSecurityEngineResult> has the following elements(note in this
binding, the client-generated secret is used to sign the message, but this signature is itself signed by the client, so that
the server can be sure that the private key holder originated the message) :
0. action = 2 - WSConstants.SIGN - the client's certificate - validated-token = true
1. action = 2 - WSConstants.SIGN - no x509 certificate - just a reference - presumably this is the signature of the
message signature
2. action = 2048 - WSConstants.DKT - no x509 certificate - key generated by client
- validated-token = false
3. action = 4 - WSConstants.ENC - encryption of the derived key
4. action = 32 - WSConstants.TS - timestamp verification
5. action = 4096 - WSConstants.BST - the client's cert so that the signature of the message signature can be verified by the server
For UNT over the transport binding, the List<WSSecurityEngineResult> has the following elements):
0. action = 1 - WSConstants.UT - the UNT
1. action = 32 - WSConstants.TS - timestamp verification
For AM over the transport binding, the List<WSSecurityEngineResult> has the following elements):
0. action = 4096 - WSConstants.BST - the BinarySecurityToken encapsulating the OpenAM session token
Given it does not seem possible to distinguish an x509 SupportingToken from a cert used for signature (though
this makes sense - the only way possession of a cert is demonstrated is by signature generation/verification), there
is really no way to identify a x509 'supporting token', other than by the failure to find any other explicit
SupportingToken type. And it does appear that the first SIGN reference is the correct reference.
Additional context - a list of Action bitmasks that don't ever seem to pertain to a SupportingToken:
WSConstants.TS - corresponds to timestamp verification
WSConstants.SC - signature confirmation - only the org.apache.ws.secruity.processor.SecurityConfirmationProcessor sets this
value - this class does not seem to do much, and may not be engaged
WSConstants.ENCR - encryption - encryption of the message in the asymmetric binding using the recipients public key/cert,
or encryption of the messge using the client-generated secret in the symmetric binding - again, no supporting token here.
WSConstants.DKT - derived key token - in the symmetric binding, relates to key/nonce generated by client
*/
final WSSecurityEngineResult untSupportingTokenResult = getUsernameTokenResult(securityEngineResults);
if (untSupportingTokenResult != null) {
return peformSaml2AuthNContextClassReferenceMapping(TokenType.USERNAME, untSupportingTokenResult);
}
final WSSecurityEngineResult openAMSessionSupportingTokenResult = getOpenAMSessionTokenResult(securityEngineResults);
if (openAMSessionSupportingTokenResult != null) {
return peformSaml2AuthNContextClassReferenceMapping(TokenType.OPENAM, openAMSessionSupportingTokenResult);
}
final WSSecurityEngineResult x509SupportingTokenResult = getX509TokenResult(securityEngineResults);
if (x509SupportingTokenResult != null) {
return peformSaml2AuthNContextClassReferenceMapping(TokenType.X509, x509SupportingTokenResult);
}
logger.error("No recognizable WSHandlerResult instances found matching an expected input token validated by " + "SecurityPolicy bindings in the DefaultSaml2XmlTokenAuthnContextMapper. Returning " + SAML2Constants.AUTH_CONTEXT_CLASS_REF_UNSPECIFIED + " as the SAML2 authn context class reference.");
return SAML2Constants.AUTH_CONTEXT_CLASS_REF_UNSPECIFIED;
} else {
logger.error("No WSSecurityEngineResult obtained from the WSHandlerResult as necessary to inspect to obtain " + "the input token validated by SecurityPolicy bindings in theDefaultSaml2XmlTokenAuthnContextMapper. " + "Returning " + SAML2Constants.AUTH_CONTEXT_CLASS_REF_UNSPECIFIED + "as the SAML2 authn context class reference.");
return SAML2Constants.AUTH_CONTEXT_CLASS_REF_UNSPECIFIED;
}
}
use of org.apache.ws.security.handler.WSHandlerResult in project nhin-d by DirectProject.
the class WSAuthenticationInInterceptor method handleMessage.
@SuppressWarnings("unchecked")
@Override
public /**
* Extract the username/password from the incoming message,
* validate it, and store the user context where CXF can get at it.
*/
void handleMessage(SoapMessage message) throws Fault {
try {
// Let the WSS4J parent do it's thing first
super.handleMessage(message);
Vector<WSHandlerResult> results = (Vector<WSHandlerResult>) message.getContextualProperty(WSHandlerConstants.RECV_RESULTS);
if (results != null && !results.isEmpty()) {
for (WSHandlerResult result : results) {
// loop through security engine results
for (WSSecurityEngineResult securityResult : (Vector<WSSecurityEngineResult>) result.getResults()) {
int action = (Integer) securityResult.get(WSSecurityEngineResult.TAG_ACTION);
// Was this a usernametoken
if (action == WSConstants.UT) {
WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) securityResult.get(WSSecurityEngineResult.TAG_PRINCIPAL);
if (principal.getPassword() == null) {
principal.setPassword("");
}
Authentication auth = new UsernamePasswordAuthenticationToken(principal.getName(), principal.getPassword());
auth = getAuthenticationManager().authenticate(auth);
if (auth.isAuthenticated()) {
_log.info("Authentication succeeds for request: User: " + principal.getName());
} else {
_log.warn("Authentication failed for request: User: " + principal.getName());
}
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
}
}
} catch (RuntimeException ex) {
_log.error("Runtime Exception caught:", ex);
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(null, null));
}
}
use of org.apache.ws.security.handler.WSHandlerResult in project OpenAM by OpenRock.
the class OpenAMSessionTokenServerInterceptor method processToken.
/**
* This method is called in-bound on the server-side - validate-request in JASPI terms. The method must validate the
* OpenAM session id with OpenAM, and, if validation is successful, populate the wss4j results with state corresponding
* to the token validation. It will also assert the relevant tokens, which means affirm that the assertions corresponding
* to the OpenAMSessionToken have been successfully fulfilled.
* @param message The message encapsulating the soap invocation.
* @throws Fault if the OpenAM session in the BinarySecurityToken in invalid.
*/
@Override
protected void processToken(SoapMessage message) throws Fault {
Header header = findSecurityHeader(message, false);
if (header == null) {
return;
}
Element el = (Element) header.getObject();
Element child = DOMUtils.getFirstElement(el);
while (child != null) {
if (WSConstants.BINARY_TOKEN_LN.equals(child.getLocalName()) && WSConstants.WSSE_NS.equals(child.getNamespaceURI()) && AMSTSConstants.AM_SESSION_TOKEN_ASSERTION_BST_VALUE_TYPE.equals(child.getAttribute("ValueType"))) {
try {
List<WSSecurityEngineResult> validationResults = validateToken(child);
if (validationResults != null) {
List<WSHandlerResult> results = CastUtils.cast((List<?>) message.get(WSHandlerConstants.RECV_RESULTS));
if (results == null) {
results = new ArrayList<WSHandlerResult>();
message.put(WSHandlerConstants.RECV_RESULTS, results);
}
WSHandlerResult rResult = new WSHandlerResult(null, validationResults);
results.add(0, rResult);
assertTokens(message);
Principal principal = (Principal) validationResults.get(0).get(WSSecurityEngineResult.TAG_PRINCIPAL);
message.put(WSS4JInInterceptor.PRINCIPAL_RESULT, principal);
SecurityContext sc = message.get(SecurityContext.class);
if (sc == null || sc.getUserPrincipal() == null) {
message.put(SecurityContext.class, new DefaultSecurityContext(principal, null));
}
}
} catch (WSSecurityException ex) {
throw new Fault(ex);
}
}
child = DOMUtils.getNextElement(child);
}
}
Aggregations