Author: anil.saldhana(a)jboss.com
Date: 2009-07-27 01:19:13 -0400 (Mon, 27 Jul 2009)
New Revision: 660
Added:
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostSignatureFormAuthenticator.java
Log:
JBID-142: HTTP/Post based SAML browser profile supports sig on both SP and IDP
Added:
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
(rev 0)
+++
identity-federation/trunk/jboss-identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPPostSignatureFormAuthenticator.java 2009-07-27
05:19:13 UTC (rev 660)
@@ -0,0 +1,136 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.identity.federation.bindings.tomcat.sp;
+
+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;
+import org.jboss.identity.federation.bindings.config.KeyProviderType;
+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;
+
+/**
+ * JBID-142: POST form authenticator that can
+ * handle signatures at the SP side
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Jul 24, 2009
+ */
+public class SPPostSignatureFormAuthenticator extends SPPostFormAuthenticator
+{
+ private static Logger log = Logger.getLogger(SPPostSignatureFormAuthenticator.class);
+
+ private TrustKeyManager keyManager;
+
+ @Override
+ public void start() throws LifecycleException
+ {
+ super.start();
+ KeyProviderType keyProvider = this.spConfiguration.getKeyProvider();
+ if(keyProvider == null)
+ throw new LifecycleException("KeyProvider is null");
+ try
+ {
+ ClassLoader tcl = SecurityActions.getContextClassLoader();
+ String keyManagerClassName = keyProvider.getClassName();
+ if(keyManagerClassName == null)
+ throw new RuntimeException("KeyManager class name is null");
+
+ Class<?> clazz = tcl.loadClass(keyManagerClassName);
+ this.keyManager = (TrustKeyManager) clazz.newInstance();
+ keyManager.setAuthProperties(keyProvider.getAuth());
+ keyManager.setValidatingAlias(keyProvider.getValidatingAlias());
+ }
+ catch(Exception e)
+ {
+ log.error("Exception reading configuration:",e);
+ throw new LifecycleException(e.getLocalizedMessage());
+ }
+ log.trace("Key Provider=" + keyProvider.getClassName());
+ }
+
+ protected void sendRequestToIDP(AuthnRequestType authnRequest, String relayState,
Response response)
+ throws IOException, SAXException, JAXBException, GeneralSecurityException
+ {
+ SAML2Request saml2Request = new SAML2Request();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ saml2Request.marshall(authnRequest, baos);
+
+ 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()));
+ }
+}
\ No newline at end of file