Author: anil.saldhana(a)jboss.com
Date: 2009-08-11 17:17:11 -0400 (Tue, 11 Aug 2009)
New Revision: 692
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectWithSignatureValve.java
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPWebBrowserSSOValve.java
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPWebRequestUtil.java
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostFormAuthenticator.java
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostSignatureFormAuthenticator.java
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/PostBindingUtil.java
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/RedirectBindingSignatureUtil.java
identity-federation/trunk/jboss-identity-seam/src/main/java/org/jboss/identity/seam/federation/SamlAuthenticationFilter.java
Log:
JBID-162: fix the saml post binding signature
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectWithSignatureValve.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectWithSignatureValve.java 2009-08-10
19:39:12 UTC (rev 691)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectWithSignatureValve.java 2009-08-11
21:17:11 UTC (rev 692)
@@ -53,7 +53,6 @@
import org.jboss.identity.federation.core.exceptions.ProcessingException;
import org.jboss.identity.federation.core.saml.v2.constants.JBossSAMLURIConstants;
import org.jboss.identity.federation.core.saml.v2.util.DocumentUtil;
-import org.jboss.identity.federation.core.saml.v2.util.SignatureUtil;
import org.jboss.identity.federation.core.util.XMLEncryptionUtil;
import org.jboss.identity.federation.saml.v2.assertion.EncryptedElementType;
import org.jboss.identity.federation.saml.v2.protocol.ResponseType;
@@ -137,20 +136,6 @@
if(sigValue == null)
return false;
- //Construct the url again
- String reqFromURL = RedirectBindingSignatureUtil.getTokenValue(queryString,
"SAMLRequest");
- String relayStateFromURL = RedirectBindingSignatureUtil.getTokenValue(queryString,
"RelayState");
- String sigAlgFromURL = RedirectBindingSignatureUtil.getTokenValue(queryString,
"SigAlg");
-
- StringBuilder sb = new StringBuilder();
- sb.append("SAMLRequest=").append(reqFromURL);
-
- if(relayStateFromURL != null && relayStateFromURL.length() > 0)
- {
- sb.append("&RelayState=").append(relayStateFromURL);
- }
- sb.append("&SigAlg=").append(sigAlgFromURL);
-
PublicKey validatingKey;
try
{
@@ -164,8 +149,8 @@
{
throw new GeneralSecurityException(e.getCause());
}
- boolean isValid = SignatureUtil.validate(sb.toString().getBytes("UTF-8"),
sigValue, validatingKey);
- return isValid;
+
+ return RedirectBindingSignatureUtil.validateSignature(queryString, validatingKey,
sigValue);
}
@Override
@@ -231,8 +216,7 @@
}
catch (MalformedURLException e)
{
- // TODO Auto-generated catch block
- e.printStackTrace();
+ throw new ParsingException(e);
}
catch (JAXBException e)
{
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPWebBrowserSSOValve.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPWebBrowserSSOValve.java 2009-08-10
19:39:12 UTC (rev 691)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPWebBrowserSSOValve.java 2009-08-11
21:17:11 UTC (rev 692)
@@ -25,6 +25,7 @@
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.Principal;
+import java.security.PublicKey;
import java.util.List;
import javax.servlet.ServletException;
@@ -43,9 +44,11 @@
import org.jboss.identity.federation.bindings.config.IDPType;
import org.jboss.identity.federation.bindings.config.KeyProviderType;
import org.jboss.identity.federation.bindings.interfaces.RoleGenerator;
+import org.jboss.identity.federation.bindings.interfaces.TrustKeyConfigurationException;
import org.jboss.identity.federation.bindings.interfaces.TrustKeyManager;
+import org.jboss.identity.federation.bindings.interfaces.TrustKeyProcessingException;
import org.jboss.identity.federation.bindings.tomcat.TomcatRoleGenerator;
-import org.jboss.identity.federation.bindings.util.PostBindingUtil;
+import org.jboss.identity.federation.bindings.util.RedirectBindingSignatureUtil;
import org.jboss.identity.federation.bindings.util.ValveUtil;
import org.jboss.identity.federation.core.exceptions.ConfigurationException;
import org.jboss.identity.federation.core.exceptions.ParsingException;
@@ -58,6 +61,10 @@
/**
* Generic Web Browser SSO valve for the IDP
+ *
+ * Handles both the SAML Redirect as well as Post Bindings
+ *
+ * Note: Most of the work is done by {@code IDPWebRequestUtil}
* @author Anil.Saldhana(a)redhat.com
* @since May 18, 2009
*/
@@ -205,8 +212,10 @@
try
{
requestAbstractType = webRequestUtil.getSAMLRequest(samlMessage);
+ boolean isPost = webRequestUtil.hasSAMLRequestInPostProfile();
boolean isValid = validate(request.getRemoteAddr(),
- new SessionHolder(samlMessage, signature, sigAlg));
+ request.getQueryString(),
+ new SessionHolder(samlMessage, signature, sigAlg), isPost);
if(!isValid)
throw new GeneralSecurityException("Validation check
failed");
@@ -327,14 +336,15 @@
}
protected boolean validate(String remoteAddress,
- SessionHolder holder) throws IOException, GeneralSecurityException
+ String queryString,
+ SessionHolder holder, boolean isPost) throws IOException,
GeneralSecurityException
{
if (holder.samlRequest == null || holder.samlRequest.length() == 0)
{
return false;
}
- if (!this.ignoreIncomingSignatures)
+ if (!this.ignoreIncomingSignatures && !isPost)
{
String sig = holder.signature;
if (sig == null || sig.length() == 0)
@@ -342,12 +352,31 @@
log.error("Signature received from SP is null:" + remoteAddress);
return false;
}
-
- return
PostBindingUtil.validateSignature(holder.samlRequest.getBytes("UTF-8"), sig,
keyManager
- .getValidatingKey(remoteAddress));
+
+ //Check if there is a signature
+ byte[] sigValue =
RedirectBindingSignatureUtil.getSignatureValueFromSignedURL(queryString);
+ if(sigValue == null)
+ return false;
+
+ PublicKey validatingKey;
+ try
+ {
+ validatingKey = keyManager.getValidatingKey(remoteAddress);
+ }
+ catch (TrustKeyConfigurationException e)
+ {
+ throw new GeneralSecurityException(e.getCause());
+ }
+ catch (TrustKeyProcessingException e)
+ {
+ throw new GeneralSecurityException(e.getCause());
+ }
+
+ return RedirectBindingSignatureUtil.validateSignature(queryString,
validatingKey, sigValue);
}
else
{
+ //Post binding no signature verification. The SAML message signature is
verified
return true;
}
}
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPWebRequestUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPWebRequestUtil.java 2009-08-10
19:39:12 UTC (rev 691)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPWebRequestUtil.java 2009-08-11
21:17:11 UTC (rev 692)
@@ -56,7 +56,6 @@
import org.jboss.identity.federation.core.saml.v2.holders.IDPInfoHolder;
import org.jboss.identity.federation.core.saml.v2.holders.IssuerInfoHolder;
import org.jboss.identity.federation.core.saml.v2.holders.SPInfoHolder;
-import org.jboss.identity.federation.core.saml.v2.holders.SignatureInfoHolder;
import org.jboss.identity.federation.core.saml.v2.util.SignatureUtil;
import org.jboss.identity.federation.saml.v2.assertion.AssertionType;
import org.jboss.identity.federation.saml.v2.assertion.AttributeStatementType;
@@ -294,21 +293,17 @@
*/
response.recycle();
String samlResponse = PostBindingUtil.base64Encode(baos.toString());
-
- SignatureInfoHolder signatureHolder = null;
+
if(supportSignature)
{
//SigAlg
String algo = signingKey.getAlgorithm();
String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(algo);
- sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
-
- byte[] signedValue = SignatureUtil.sign(samlResponse, signingKey);
- signatureHolder = new SignatureInfoHolder(signedValue,sigAlg);
+ sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
}
PostBindingUtil.sendPost(new
DestinationInfoHolder(responseType.getDestination(),
- samlResponse, relayState), signatureHolder, response, false);
+ samlResponse, relayState), response, false);
}
}
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostFormAuthenticator.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostFormAuthenticator.java 2009-08-10
19:39:12 UTC (rev 691)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostFormAuthenticator.java 2009-08-11
21:17:11 UTC (rev 692)
@@ -154,7 +154,7 @@
String samlMessage = PostBindingUtil.base64Encode(baos.toString());
String destination = authnRequest.getDestination();
PostBindingUtil.sendPost(new DestinationInfoHolder(destination, samlMessage,
relayState),
- null,response, true);
+ response, true);
}
protected AuthnRequestType createSAMLRequestMessage(String relayState, Response
response)
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostSignatureFormAuthenticator.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostSignatureFormAuthenticator.java 2009-08-10
19:39:12 UTC (rev 691)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostSignatureFormAuthenticator.java 2009-08-11
21:17:11 UTC (rev 692)
@@ -23,14 +23,11 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.net.URLEncoder;
import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
import javax.xml.bind.JAXBException;
import org.apache.catalina.LifecycleException;
-import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.log4j.Logger;
import org.jboss.identity.federation.api.saml.v2.request.SAML2Request;
@@ -38,8 +35,6 @@
import org.jboss.identity.federation.bindings.interfaces.TrustKeyManager;
import org.jboss.identity.federation.bindings.util.PostBindingUtil;
import org.jboss.identity.federation.core.saml.v2.holders.DestinationInfoHolder;
-import org.jboss.identity.federation.core.saml.v2.holders.SignatureInfoHolder;
-import org.jboss.identity.federation.core.saml.v2.util.SignatureUtil;
import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
import org.xml.sax.SAXException;
@@ -54,7 +49,19 @@
private static Logger log = Logger.getLogger(SPPostSignatureFormAuthenticator.class);
private TrustKeyManager keyManager;
+
+ private boolean signAssertions = false;
+
+ public boolean isSignAssertions()
+ {
+ return signAssertions;
+ }
+ public void setSignAssertions(boolean signAssertions)
+ {
+ this.signAssertions = signAssertions;
+ }
+
@Override
public void start() throws LifecycleException
{
@@ -92,45 +99,7 @@
String samlMessage = PostBindingUtil.base64Encode(baos.toString());
String destination = authnRequest.getDestination();
- //Get the signing key
- PrivateKey signingKey = keyManager.getSigningKey();
-
- //SigAlg
- String algo = signingKey.getAlgorithm();
- String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(algo);
-
- sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
-
- byte[] signedValue = SignatureUtil.sign(samlMessage, signingKey);
-
PostBindingUtil.sendPost(new DestinationInfoHolder(destination, samlMessage,
relayState),
- new SignatureInfoHolder(signedValue,sigAlg),response, true);
- }
-
- @Override
- protected boolean validate(Request request) throws IOException,
GeneralSecurityException
- {
- boolean result = super.validate(request);
- if( result == false)
- return result;
-
- String samlMessage = request.getParameter("SAMLResponse");
-
- //Check if there is a signature
- String sig = request.getParameter("Signature");
- if(sig == null || sig.length() == 0)
- {
- log.error("Signature Value missing in response from IDP");
- return false;
- }
- String sigAlg = request.getParameter("sigAlg");
- if(sigAlg == null || sigAlg.length() == 0)
- {
- log.error("Signature Algorithm missing in the response from IDP");
- return false;
- }
-
- return PostBindingUtil.validateSignature(samlMessage.getBytes("UTF-8"),
sig,
- keyManager.getValidatingKey(request.getRemoteAddr()));
- }
+ response, true);
+ }
}
\ No newline at end of file
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/PostBindingUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/PostBindingUtil.java 2009-08-10
19:39:12 UTC (rev 691)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/PostBindingUtil.java 2009-08-11
21:17:11 UTC (rev 692)
@@ -23,16 +23,12 @@
import java.io.IOException;
import java.io.PrintWriter;
-import java.security.GeneralSecurityException;
-import java.security.PublicKey;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.jboss.identity.federation.api.util.Base64;
import org.jboss.identity.federation.core.saml.v2.holders.DestinationInfoHolder;
-import org.jboss.identity.federation.core.saml.v2.holders.SignatureInfoHolder;
-import org.jboss.identity.federation.core.saml.v2.util.SignatureUtil;
/**
* Utility for the HTTP/Post binding
@@ -62,7 +58,6 @@
* @throws IOException
*/
public static void sendPost(DestinationInfoHolder holder,
- SignatureInfoHolder sigHolder,
HttpServletResponse response,
boolean sendToIDP)
throws IOException
@@ -95,16 +90,7 @@
{
builder.append("<INPUT TYPE=\"HIDDEN\"
NAME=\"RelayState\" " +
"VALUE=\"" + relayState + "\"/>");
- }
- if(sigHolder != null)
- {
- byte[] sigValue = sigHolder.getSignatureValue();
-
- builder.append("<INPUT TYPE=\"HIDDEN\"
NAME=\"Signature\" " +
- "VALUE=\"" + Base64.encodeBytes(sigValue,
Base64.DONT_BREAK_LINES) + "\"/>");
- builder.append("<INPUT TYPE=\"HIDDEN\"
NAME=\"sigAlg\" " +
- "VALUE=\"" + sigHolder.getSigAlg() +
"\"/>");
- }
+ }
builder.append("</FORM></BODY></HTML>");
String str = builder.toString();
@@ -113,23 +99,6 @@
out.close();
}
- public static boolean validateSignature(byte[] message, String base64encodedSigValue,
PublicKey validatingKey)
- throws GeneralSecurityException
- {
- byte[] sigValue = null;
- if(base64encodedSigValue != null && base64encodedSigValue.length() > 0)
- {
- sigValue = Base64.decode(base64encodedSigValue);
- }
-
- if(sigValue == null)
- {
- log.error("Signature missing");
- return false;
- }
- return SignatureUtil.validate(message, sigValue, validatingKey);
- }
-
private static void common(String destination, HttpServletResponse response)
{
response.setCharacterEncoding("UTF-8");
Modified:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/RedirectBindingSignatureUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/RedirectBindingSignatureUtil.java 2009-08-10
19:39:12 UTC (rev 691)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/RedirectBindingSignatureUtil.java 2009-08-11
21:17:11 UTC (rev 692)
@@ -23,9 +23,11 @@
import java.io.IOException;
import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
+import java.security.PublicKey;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
@@ -217,6 +219,27 @@
return getTokenValue(getToken(queryString, token));
}
+ public static boolean validateSignature(String queryString,
+ PublicKey validatingKey, byte[] sigValue ) throws UnsupportedEncodingException,
GeneralSecurityException
+ {
+ //Construct the url again
+ String reqFromURL = RedirectBindingSignatureUtil.getTokenValue(queryString,
"SAMLRequest");
+ String relayStateFromURL = RedirectBindingSignatureUtil.getTokenValue(queryString,
"RelayState");
+ String sigAlgFromURL = RedirectBindingSignatureUtil.getTokenValue(queryString,
"SigAlg");
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("SAMLRequest=").append(reqFromURL);
+
+ if(relayStateFromURL != null && relayStateFromURL.length() > 0)
+ {
+ sb.append("&RelayState=").append(relayStateFromURL);
+ }
+ sb.append("&SigAlg=").append(sigAlgFromURL);
+
+
+ return SignatureUtil.validate(sb.toString().getBytes("UTF-8"), sigValue,
validatingKey);
+ }
+
//***************** Private Methods **************
private static byte[] computeSignature(
Modified:
identity-federation/trunk/jboss-identity-seam/src/main/java/org/jboss/identity/seam/federation/SamlAuthenticationFilter.java
===================================================================
---
identity-federation/trunk/jboss-identity-seam/src/main/java/org/jboss/identity/seam/federation/SamlAuthenticationFilter.java 2009-08-10
19:39:12 UTC (rev 691)
+++
identity-federation/trunk/jboss-identity-seam/src/main/java/org/jboss/identity/seam/federation/SamlAuthenticationFilter.java 2009-08-11
21:17:11 UTC (rev 692)
@@ -57,6 +57,7 @@
import org.jboss.identity.federation.bindings.tomcat.sp.SPUtil;
import org.jboss.identity.federation.bindings.util.HTTPRedirectUtil;
import org.jboss.identity.federation.bindings.util.PostBindingUtil;
+import org.jboss.identity.federation.bindings.util.RedirectBindingSignatureUtil;
import org.jboss.identity.federation.bindings.util.RedirectBindingUtil;
import org.jboss.identity.federation.core.exceptions.ConfigurationException;
import org.jboss.identity.federation.core.exceptions.ParsingException;
@@ -110,6 +111,7 @@
* </dl>
*
* @author Marcel Kolsteren
+ * @author Anil Saldhana
*/
@Scope(APPLICATION)
@Name("org.jboss.identity.seam.federation.samlAuthenticationFilter")
@@ -170,7 +172,7 @@
{
// Received an authentication response from the IDP.
- AuthenticatedUser user = processIDPResponse(request);
+ AuthenticatedUser user = processIDPResponse((HttpServletRequest) request);
if (user != null)
{
// Login the user. This ends with a redirect to the URL that was requested by
the user.
@@ -235,7 +237,7 @@
}.run();
}
- private AuthenticatedUser processIDPResponse(ServletRequest request)
+ private AuthenticatedUser processIDPResponse(HttpServletRequest request)
{
String samlResponse = request.getParameter("SAMLResponse");
@@ -378,10 +380,8 @@
return user;
}
- private boolean validateSignature(ServletRequest request)
- {
- String samlMessage = request.getParameter("SAMLResponse");
-
+ private boolean validateSignature(HttpServletRequest request)
+ {
// Check if there is a signature
String signature = request.getParameter("Signature");
if (signature == null || signature.length() == 0)
@@ -398,7 +398,14 @@
try
{
- return
PostBindingUtil.validateSignature(samlMessage.getBytes("UTF-8"), signature,
publicKeyOfIDP);
+ if("GET".equalsIgnoreCase(request.getMethod()))
+ {
+ String queryString = request.getQueryString();
+ byte[] sigValue =
RedirectBindingSignatureUtil.getSignatureValueFromSignedURL(queryString);
+
+ return RedirectBindingSignatureUtil.validateSignature(queryString,
this.publicKeyOfIDP, sigValue);
+ }
+ return true;
}
catch (UnsupportedEncodingException e)
{
@@ -408,6 +415,10 @@
{
throw new RuntimeException(e);
}
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
}
private PublicKey getPublicKeyOfIDP()
@@ -471,7 +482,7 @@
{
DestinationInfoHolder destinationInfoHolder = new
DestinationInfoHolder(destination, samlMessage, Integer
.toString(relayState));
- PostBindingUtil.sendPost(destinationInfoHolder, null, response, true);
+ PostBindingUtil.sendPost(destinationInfoHolder, response, true);
}
}
catch (ConfigurationException e)