WebServiceContext context
) {
long start = System.currentTimeMillis();
TokenProviderParameters providerParameters = new TokenProviderParameters();
try {
RequestParser requestParser = parseRequest(request, context);
providerParameters = createTokenProviderParameters(requestParser, context);
// Check if the requested claims can be handled by the configured claim handlers
ClaimCollection requestedClaims = providerParameters.getRequestedPrimaryClaims();
checkClaimsSupport(requestedClaims);
requestedClaims = providerParameters.getRequestedSecondaryClaims();
checkClaimsSupport(requestedClaims);
providerParameters.setClaimsManager(claimsManager);
String realm = providerParameters.getRealm();
TokenRequirements tokenRequirements = requestParser.getTokenRequirements();
String tokenType = tokenRequirements.getTokenType();
if (stsProperties.getSamlRealmCodec() != null) {
SamlAssertionWrapper assertion = fetchSAMLAssertionFromWSSecuritySAMLToken(context);
if (assertion != null) {
String wssecRealm = stsProperties.getSamlRealmCodec().getRealmFromToken(assertion);
SAMLTokenPrincipal samlPrincipal = new SAMLTokenPrincipalImpl(assertion);
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("SAML token realm of user '" + samlPrincipal.getName() + "' is " + wssecRealm);
}
ReceivedToken wssecToken = new ReceivedToken(assertion.getElement());
wssecToken.setState(STATE.VALID);
TokenValidatorResponse tokenResponse = new TokenValidatorResponse();
tokenResponse.setPrincipal(samlPrincipal);
tokenResponse.setToken(wssecToken);
tokenResponse.setTokenRealm(wssecRealm);
tokenResponse.setAdditionalProperties(new HashMap<String, Object>());
processValidToken(providerParameters, wssecToken, tokenResponse);
providerParameters.setPrincipal(wssecToken.getPrincipal());
}
}
// Validate OnBehalfOf token if present
if (providerParameters.getTokenRequirements().getOnBehalfOf() != null) {
ReceivedToken validateTarget = providerParameters.getTokenRequirements().getOnBehalfOf();
TokenValidatorResponse tokenResponse = validateReceivedToken(
context, realm, tokenRequirements, validateTarget);
if (tokenResponse == null) {
LOG.fine("No Token Validator has been found that can handle this token");
} else if (validateTarget.getState().equals(STATE.INVALID)) {
throw new STSException("Incoming token is invalid", STSException.REQUEST_FAILED);
} else if (validateTarget.getState().equals(STATE.VALID)) {
processValidToken(providerParameters, validateTarget, tokenResponse);
} else {
//[TODO] Add plugin for validation out-of-band
// Example:
// If the requestor is in the possession of a certificate (mutual ssl handshake)
// the STS trusts the token sent in OnBehalfOf element
}
Principal tokenPrincipal = null;
Set<Principal> tokenRoles = null;
if (tokenResponse != null) {
Map<String, Object> additionalProperties = tokenResponse.getAdditionalProperties();
if (additionalProperties != null) {
providerParameters.setAdditionalProperties(additionalProperties);
}
tokenPrincipal = tokenResponse.getPrincipal();
tokenRoles = tokenResponse.getRoles();
}
// See whether OnBehalfOf is allowed or not
performDelegationHandling(requestParser, context,
providerParameters.getTokenRequirements().getOnBehalfOf(),
tokenPrincipal, tokenRoles);
}
// See whether ActAs is allowed or not
// TODO Validate ActAs
if (providerParameters.getTokenRequirements().getActAs() != null) {
performDelegationHandling(requestParser, context,
providerParameters.getTokenRequirements().getActAs(),
null, null);
}
// create token
TokenProviderResponse tokenResponse = null;
for (TokenProvider tokenProvider : tokenProviders) {
boolean canHandle = false;
if (realm == null) {
canHandle = tokenProvider.canHandleToken(tokenType);
} else {
canHandle = tokenProvider.canHandleToken(tokenType, realm);
}
if (canHandle) {
try {
tokenResponse = tokenProvider.createToken(providerParameters);
} catch (STSException ex) {
LOG.log(Level.WARNING, "", ex);
throw ex;
} catch (RuntimeException ex) {
LOG.log(Level.WARNING, "", ex);
throw new STSException("Error in providing a token", ex, STSException.REQUEST_FAILED);
}
break;
}
}
if (tokenResponse == null || tokenResponse.getToken() == null) {
LOG.log(Level.WARNING, "No token provider found for requested token type: " + tokenType);
throw new STSException(
"No token provider found for requested token type: " + tokenType,
STSException.REQUEST_FAILED
);
}
// prepare response
try {
KeyRequirements keyRequirements = requestParser.getKeyRequirements();
EncryptionProperties encryptionProperties = providerParameters.getEncryptionProperties();
RequestSecurityTokenResponseType response =
createResponse(
encryptionProperties, tokenResponse, tokenRequirements, keyRequirements, context
);