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
*/