cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1341470 - in /cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso: AbstractSSOSpHandler.java AbstractServiceProviderFilter.java SamlPostBindingFilter.java SamlRedirectBindingFilter.java
Date Tue, 22 May 2012 13:30:20 GMT
Author: coheigea
Date: Tue May 22 13:30:20 2012
New Revision: 1341470

URL: http://svn.apache.org/viewvc?rev=1341470&view=rev
Log:
Add support for signing Authentication Requests using the POST Binding

Modified:
    cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractSSOSpHandler.java
    cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java
    cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java
    cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java

Modified: cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractSSOSpHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractSSOSpHandler.java?rev=1341470&r1=1341469&r2=1341470&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractSSOSpHandler.java
(original)
+++ cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractSSOSpHandler.java
Tue May 22 13:30:20 2012
@@ -27,9 +27,12 @@ import java.util.logging.Logger;
 
 import javax.security.auth.callback.CallbackHandler;
 
+import org.apache.cxf.Bus;
 import org.apache.cxf.common.classloader.ClassLoaderUtils;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.cxf.resource.ResourceManager;
 import org.apache.cxf.rs.security.saml.sso.state.SPStateManager;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.components.crypto.Crypto;
@@ -150,8 +153,13 @@ public class AbstractSSOSpHandler {
             properties = (Properties)o;
         } else if (o instanceof String) {
             URL url = null;
+            Bus bus = PhaseInterceptorChain.getCurrentMessage().getExchange().getBus();
+            ResourceManager rm = bus.getExtension(ResourceManager.class);
+            url = rm.resolveResource((String)o, URL.class);
             try {
-                url = ClassLoaderUtils.getResource((String)o, AbstractSSOSpHandler.class);
+                if (url == null) {
+                    url = ClassLoaderUtils.getResource((String)o, AbstractSSOSpHandler.class);
+                }
                 if (url == null) {
                     url = new URL((String)o);
                 }

Modified: cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java?rev=1341470&r1=1341469&r2=1341470&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java
(original)
+++ cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/AbstractServiceProviderFilter.java
Tue May 22 13:30:20 2012
@@ -248,6 +248,9 @@ public abstract class AbstractServicePro
             authnRequestBuilder.createAuthnRequest(
                 m, getIssuerId(m), getAbsoluteAssertionServiceAddress(m)
             );
+        if (isSignRequest()) {
+            signAuthnRequest(authnRequest);
+        }
         Element authnRequestElement = OpenSAMLUtil.toDom(authnRequest, doc);
         String authnRequestEncoded = deflateEncodeAuthnRequest(authnRequestElement);
         
@@ -274,6 +277,8 @@ public abstract class AbstractServicePro
         return info;
     }
     
+    protected abstract void signAuthnRequest(AuthnRequest authnRequest) throws Exception;
+    
     private String getAbsoluteAssertionServiceAddress(Message m) {
         if (assertionConsumerServiceAddress == null) {    
             //TODO: Review the possibility of using this filter

Modified: cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java?rev=1341470&r1=1341469&r2=1341470&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java
(original)
+++ cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlPostBindingFilter.java
Tue May 22 13:30:20 2012
@@ -18,6 +18,10 @@
  */
 package org.apache.cxf.rs.security.saml.sso;
 
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.callback.CallbackHandler;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
@@ -25,6 +29,18 @@ import javax.ws.rs.core.Response;
 import org.apache.cxf.jaxrs.ext.MessageContextImpl;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.message.Message;
+import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoType;
+import org.apache.ws.security.saml.ext.OpenSAMLUtil;
+import org.opensaml.common.SignableSAMLObject;
+import org.opensaml.saml2.core.AuthnRequest;
+import org.opensaml.xml.security.x509.BasicX509Credential;
+import org.opensaml.xml.security.x509.X509KeyInfoGeneratorFactory;
+import org.opensaml.xml.signature.KeyInfo;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.signature.SignatureConstants;
 
 public class SamlPostBindingFilter extends AbstractServiceProviderFilter {
     
@@ -36,8 +52,8 @@ public class SamlPostBindingFilter exten
                 SamlRequestInfo info = createSamlRequestInfo(m);
                 info.setIdpServiceAddress(getIdpServiceAddress());
                 // This depends on RequestDispatcherProvider linking
-                // SamlResponseInfo with the jsp page which will fill
-                // in the XHTML form using SamlResponseInfo
+                // SamlRequestInfo with the jsp page which will fill
+                // in the XHTML form using SamlRequestInfo
                 // in principle we could've built the XHTML form right here
                 // but it will be cleaner to get that done in JSP
                 
@@ -60,5 +76,80 @@ public class SamlPostBindingFilter exten
         }
     }
     
+    protected void signAuthnRequest(AuthnRequest authnRequest) throws Exception {
+        Crypto crypto = getSignatureCrypto();
+        if (crypto == null) {
+            LOG.fine("No crypto instance of properties file configured for signature");
+            throw new WebApplicationException();
+        }
+        String signatureUser = getSignatureUsername();
+        if (signatureUser == null) {
+            LOG.fine("No user configured for signature");
+            throw new WebApplicationException();
+        }
+        CallbackHandler callbackHandler = getCallbackHandler();
+        if (callbackHandler == null) {
+            LOG.fine("No CallbackHandler configured to supply a password for signature");
+            throw new WebApplicationException();
+        }
+        
+        CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+        cryptoType.setAlias(signatureUser);
+        X509Certificate[] issuerCerts = crypto.getX509Certificates(cryptoType);
+        if (issuerCerts == null) {
+            throw new WSSecurityException(
+                "No issuer certs were found to sign the request using name: " + signatureUser
+            );
+        }
+
+        String sigAlgo = SSOConstants.RSA_SHA1;
+        String pubKeyAlgo = issuerCerts[0].getPublicKey().getAlgorithm();
+        LOG.fine("automatic sig algo detection: " + pubKeyAlgo);
+        if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
+            sigAlgo = SSOConstants.DSA_SHA1;
+        }
+        LOG.fine("Using Signature algorithm " + sigAlgo);
+        
+        // Get the password
+        WSPasswordCallback[] cb = {new WSPasswordCallback(signatureUser, WSPasswordCallback.SIGNATURE)};
+        callbackHandler.handle(cb);
+        String password = cb[0].getPassword();
+        
+        // Get the private key
+        PrivateKey privateKey = null;
+        try {
+            privateKey = crypto.getPrivateKey(signatureUser, password);
+        } catch (Exception ex) {
+            throw new WSSecurityException(ex.getMessage(), ex);
+        }
+        
+        // Create the signature
+        Signature signature = OpenSAMLUtil.buildSignature();
+        signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+        signature.setSignatureAlgorithm(sigAlgo);
+        
+        BasicX509Credential signingCredential = new BasicX509Credential();
+        signingCredential.setEntityCertificate(issuerCerts[0]);
+        signingCredential.setPrivateKey(privateKey);
+
+        signature.setSigningCredential(signingCredential);
+
+        X509KeyInfoGeneratorFactory kiFactory = new X509KeyInfoGeneratorFactory();
+        kiFactory.setEmitEntityCertificate(true);
+        
+        try {
+            KeyInfo keyInfo = kiFactory.newInstance().generate(signingCredential);
+            signature.setKeyInfo(keyInfo);
+        } catch (org.opensaml.xml.security.SecurityException ex) {
+            throw new WSSecurityException(
+                    "Error generating KeyInfo from signing credential", ex);
+        }
+        
+        SignableSAMLObject signableObject = (SignableSAMLObject) authnRequest;
+        signableObject.setSignature(signature);
+        signableObject.releaseDOM();
+        signableObject.releaseChildrenDOM(true);
+        
+    }
     
 }

Modified: cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java?rev=1341470&r1=1341469&r2=1341470&view=diff
==============================================================================
--- cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java
(original)
+++ cxf/trunk/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlRedirectBindingFilter.java
Tue May 22 13:30:20 2012
@@ -35,6 +35,7 @@ import org.apache.ws.security.WSSecurity
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.components.crypto.CryptoType;
 import org.apache.ws.security.util.Base64;
+import org.opensaml.saml2.core.AuthnRequest;
 
 public class SamlRedirectBindingFilter extends AbstractServiceProviderFilter {
     
@@ -72,6 +73,10 @@ public class SamlRedirectBindingFilter e
         }
     }
     
+    protected void signAuthnRequest(AuthnRequest authnRequest) throws Exception {
+        // Do nothing as we sign the request in a different way for the redirect binding
+    }
+    
     /**
      * Sign a request according to the redirect binding spec for Web SSO
      */



Mime
View raw message