Author: dehort
Date: 2012-07-10 15:34:17 -0400 (Tue, 10 Jul 2012)
New Revision: 1568
Modified:
product/branches/2.0.2_JBPAPP-9307/picketlink-core/src/main/java/org/picketlink/identity/federation/bindings/tomcat/idp/IDPWebBrowserSSOValve.java
Log:
Backporting PLFED-248 to 2.0.2
[JBPAPP-9307]
Modified:
product/branches/2.0.2_JBPAPP-9307/picketlink-core/src/main/java/org/picketlink/identity/federation/bindings/tomcat/idp/IDPWebBrowserSSOValve.java
===================================================================
---
product/branches/2.0.2_JBPAPP-9307/picketlink-core/src/main/java/org/picketlink/identity/federation/bindings/tomcat/idp/IDPWebBrowserSSOValve.java 2012-07-10
19:31:43 UTC (rev 1567)
+++
product/branches/2.0.2_JBPAPP-9307/picketlink-core/src/main/java/org/picketlink/identity/federation/bindings/tomcat/idp/IDPWebBrowserSSOValve.java 2012-07-10
19:34:17 UTC (rev 1568)
@@ -28,7 +28,9 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.net.URI;
+import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.Principal;
import java.security.PublicKey;
@@ -182,6 +184,8 @@
*/
private final Lock chainLock = new ReentrantLock();
+ private Boolean validatingAliasToTokenIssuer = false;
+
//Set a list of attributes we are interested in separated by comma
public void setAttributeList(String attribList)
{
@@ -220,6 +224,20 @@
}
/**
+ * PLFED-248
+ * Allows to validate the token's signature against the keystore using the
token's issuer.
+ */
+ public void setValidatingAliasToTokenIssuer(Boolean validatingAliasToTokenIssuer)
+ {
+ this.validatingAliasToTokenIssuer = validatingAliasToTokenIssuer;
+ }
+
+ public Boolean getValidatingAliasToTokenIssuer()
+ {
+ return validatingAliasToTokenIssuer;
+ }
+
+ /**
* IDP should not do any attributes such as generation of roles etc
* @param ignoreAttributes
*/
@@ -489,8 +507,6 @@
Boolean requestedPostProfile = null;
- //Get the SAML Request Message
- RequestAbstractType requestAbstractType = null;
String samlRequestMessage = (String)
session.getNote(GeneralConstants.SAML_REQUEST_KEY);
String relayState = (String) session.getNote(GeneralConstants.RELAY_STATE);
@@ -511,15 +527,23 @@
{
samlDocumentHolder = webRequestUtil.getSAMLDocumentHolder(samlRequestMessage);
samlObject = samlDocumentHolder.getSamlObject();
+
+ if (!(samlObject instanceof RequestAbstractType)) {
+ throw new RuntimeException(ErrorCodes.WRONG_TYPE +
samlObject.getClass().getName());
+ }
+ //Get the SAML Request Message
+ RequestAbstractType requestAbstractType = (RequestAbstractType) samlObject;
+ String issuer = requestAbstractType.getIssuer().getValue();
+
boolean isPost = webRequestUtil.hasSAMLRequestInPostProfile();
- boolean isValid = validate(request.getRemoteAddr(), request.getQueryString(),
new SessionHolder(
+ String tokenSignatureValidatingAlias = getTokenSignatureValidatingAlias(request,
issuer);
+ boolean isValid = validate(tokenSignatureValidatingAlias,
request.getQueryString(), new SessionHolder(
samlRequestMessage, signature, sigAlg), isPost);
if (!isValid)
throw new GeneralSecurityException(ErrorCodes.VALIDATION_CHECK_FAILED);
- String issuer = null;
IssuerInfoHolder idpIssuer = new IssuerInfoHolder(this.identityURL);
ProtocolContext protocolContext = new HTTPContext(request, response,
context.getServletContext());
//Create the request/response
@@ -545,12 +569,13 @@
if (this.keyManager != null)
{
- String remoteHost = request.getRemoteAddr();
if (trace)
{
- log.trace("Remote Host=" + remoteHost);
+ log.trace("Remote Host=" + request.getRemoteAddr());
+ log.trace("Validating Alias=" + tokenSignatureValidatingAlias);
}
- PublicKey validatingKey = CoreConfigUtil.getValidatingKey(keyManager,
remoteHost);
+
+ PublicKey validatingKey = CoreConfigUtil.getValidatingKey(keyManager,
tokenSignatureValidatingAlias);
requestOptions.put(GeneralConstants.SENDER_PUBLIC_KEY, validatingKey);
requestOptions.put(GeneralConstants.DECRYPTING_KEY,
keyManager.getSigningKey());
}
@@ -572,31 +597,24 @@
log.trace("Handlers are=" + handlers);
}
- if (samlObject instanceof RequestAbstractType)
+ webRequestUtil.isTrusted(issuer);
+
+ if (handlers != null)
{
- requestAbstractType = (RequestAbstractType) samlObject;
- issuer = requestAbstractType.getIssuer().getValue();
- webRequestUtil.isTrusted(issuer);
-
- if (handlers != null)
+ try
{
- try
+ chainLock.lock();
+ for (SAML2Handler handler : handlers)
{
- chainLock.lock();
- for (SAML2Handler handler : handlers)
- {
- handler.handleRequestType(saml2HandlerRequest,
saml2HandlerResponse);
- willSendRequest = saml2HandlerResponse.getSendRequest();
- }
+ handler.handleRequestType(saml2HandlerRequest, saml2HandlerResponse);
+ willSendRequest = saml2HandlerResponse.getSendRequest();
}
- finally
- {
- chainLock.unlock();
- }
}
+ finally
+ {
+ chainLock.unlock();
+ }
}
- else
- throw new RuntimeException(ErrorCodes.WRONG_TYPE +
samlObject.getClass().getName());
samlResponse = saml2HandlerResponse.getResultingDocument();
relayState = saml2HandlerResponse.getRelayState();
@@ -654,6 +672,33 @@
return;
}
+ /**
+ * Returns the alias to be used for the token's signature verification.
+ *
+ * @param request
+ * @param issuer
+ * @return
+ */
+ private String getTokenSignatureValidatingAlias(Request request, String issuer)
+ {
+ String issuerHost = request.getRemoteAddr();
+
+ if (this.validatingAliasToTokenIssuer) {
+ try
+ {
+ issuerHost = new URL(issuer).getHost();
+ }
+ catch (MalformedURLException e)
+ {
+ if (trace) {
+ log.trace("Token issuer is not a valid URL: " + issuer + ".
Using the requester address instead.", e);
+ }
+ }
+ }
+
+ return issuerHost;
+ }
+
protected void processSAMLResponseMessage(IDPWebRequestUtil webRequestUtil, Request
request, Response response)
throws ServletException, IOException
{
@@ -678,17 +723,22 @@
cleanUpSessionNote(request);
- StatusResponseType statusResponseType = null;
try
{
samlDocumentHolder = webRequestUtil.getSAMLDocumentHolder(samlResponseMessage);
samlObject = samlDocumentHolder.getSamlObject();
-
+
+ if (!(samlObject instanceof StatusResponseType))
+ {
+ throw new RuntimeException(ErrorCodes.WRONG_TYPE +
samlObject.getClass().getName());
+ }
+
boolean isPost = webRequestUtil.hasSAMLRequestInPostProfile();
boolean isValid = false;
-
- String remoteAddress = request.getRemoteAddr();
-
+ StatusResponseType statusResponseType = (StatusResponseType) samlObject;
+ String issuer = statusResponseType.getIssuer().getValue();
+ String tokenValidatingAlias = getTokenSignatureValidatingAlias(request,
issuer);
+
if (isPost)
{
//Validate
@@ -696,7 +746,7 @@
if (ignoreIncomingSignatures == false && signOutgoingMessages ==
true)
{
- PublicKey publicKey = keyManager.getValidatingKey(remoteAddress);
+ PublicKey publicKey = keyManager.getValidatingKey(tokenValidatingAlias);
isValid = samlSignature.validate(samlDocumentHolder.getSamlDocument(),
publicKey);
}
else
@@ -704,14 +754,13 @@
}
else
{
- isValid = validate(remoteAddress, request.getQueryString(), new
SessionHolder(samlResponseMessage,
+ isValid = validate(tokenValidatingAlias, request.getQueryString(), new
SessionHolder(samlResponseMessage,
signature, sigAlg), isPost);
}
if (!isValid)
throw new GeneralSecurityException(ErrorCodes.VALIDATION_CHECK_FAILED);
- String issuer = null;
IssuerInfoHolder idpIssuer = new IssuerInfoHolder(this.identityURL);
ProtocolContext protocolContext = new HTTPContext(request, response,
context.getServletContext());
//Create the request/response
@@ -723,32 +772,25 @@
Set<SAML2Handler> handlers = chain.handlers();
- if (samlObject instanceof StatusResponseType)
+ webRequestUtil.isTrusted(issuer);
+
+ if (handlers != null)
{
- statusResponseType = (StatusResponseType) samlObject;
- issuer = statusResponseType.getIssuer().getValue();
- webRequestUtil.isTrusted(issuer);
-
- if (handlers != null)
+ try
{
- try
+ chainLock.lock();
+ for (SAML2Handler handler : handlers)
{
- chainLock.lock();
- for (SAML2Handler handler : handlers)
- {
- handler.reset();
- handler.handleStatusResponseType(saml2HandlerRequest,
saml2HandlerResponse);
- willSendRequest = saml2HandlerResponse.getSendRequest();
- }
+ handler.reset();
+ handler.handleStatusResponseType(saml2HandlerRequest,
saml2HandlerResponse);
+ willSendRequest = saml2HandlerResponse.getSendRequest();
}
- finally
- {
- chainLock.unlock();
- }
}
+ finally
+ {
+ chainLock.unlock();
+ }
}
- else
- throw new RuntimeException(ErrorCodes.WRONG_TYPE +
samlObject.getClass().getName());
samlResponse = saml2HandlerResponse.getResultingDocument();
relayState = saml2HandlerResponse.getRelayState();