Check SAML Subject of AuthnRequest

Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/c564a8b8
Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/c564a8b8
Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/c564a8b8

Branch: refs/heads/master
Commit: c564a8b8f16134a83ae4eb02e7f1fc1b3714d1c1
Parents: a1fba8d
Author: Colm O hEigeartaigh <[email protected]>
Authored: Wed Mar 30 14:00:59 2016 +0100
Committer: Colm O hEigeartaigh <[email protected]>
Committed: Wed Mar 30 17:43:11 2016 +0100

----------------------------------------------------------------------
 .../beans/samlsso/AuthnRequestValidator.java    | 39 ++++++++++++++------
 .../idp/beans/samlsso/SamlResponseCreator.java  | 22 ++++++++++-
 2 files changed, 47 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/c564a8b8/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestValidator.java
----------------------------------------------------------------------
diff --git 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestValidator.java
 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestValidator.java
index 6a892a9..cb90ed0 100644
--- 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestValidator.java
+++ 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestValidator.java
@@ -72,6 +72,33 @@ public class AuthnRequestValidator {
         throws Exception {
         AuthnRequest authnRequest = 
             (AuthnRequest)WebUtils.getAttributeFromFlowScope(context, 
IdpConstants.SAML_AUTHN_REQUEST);
+        
+        validateSignature(context, authnRequest, idp, signature, relayState, 
samlRequest, realm);
+        
+        if (authnRequest.getIssuer() == null) {
+            LOG.debug("No Issuer is present in the AuthnRequest");
+            throw new ProcessingException(TYPE.BAD_REQUEST);
+        }
+        
+        String format = authnRequest.getIssuer().getFormat();
+        if (format != null
+            && 
!"urn:oasis:names:tc:SAML:2.0:nameid-format:entity".equals(format)) {
+            LOG.debug("An invalid Format attribute was received: {}", format);
+            throw new ProcessingException(TYPE.BAD_REQUEST);
+        }
+        
+        // No SubjectConfirmation Elements are allowed
+        if (authnRequest.getSubject() != null 
+            && authnRequest.getSubject().getSubjectConfirmations() != null
+            && !authnRequest.getSubject().getSubjectConfirmations().isEmpty()) 
{
+            LOG.debug("An invalid SubjectConfirmation Element was received");
+            throw new ProcessingException(TYPE.BAD_REQUEST);
+        }
+    }
+    
+    private void validateSignature(RequestContext context, AuthnRequest 
authnRequest, Idp idp, 
+                                   String signature, String relayState, String 
samlRequest, 
+                                   String realm) throws Exception {
         if (authnRequest.isSigned()) {
             // Check destination
             checkDestination(context, authnRequest);
@@ -106,18 +133,6 @@ public class AuthnRequestValidator {
             LOG.debug("No signature is present, therefore the request is 
rejected");
             throw new ProcessingException(TYPE.BAD_REQUEST);
         }
-        
-        if (authnRequest.getIssuer() == null) {
-            LOG.debug("No Issuer is present in the AuthnRequest");
-            throw new ProcessingException(TYPE.BAD_REQUEST);
-        }
-        
-        String format = authnRequest.getIssuer().getFormat();
-        if (format != null
-            && 
!"urn:oasis:names:tc:SAML:2.0:nameid-format:entity".equals(format)) {
-            LOG.debug("An invalid Format attribute was received: {}", format);
-            throw new ProcessingException(TYPE.BAD_REQUEST);
-        }
     }
     
     private X509Certificate getValidatingCertificate(Idp idp, String realm) 

http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/c564a8b8/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/SamlResponseCreator.java
----------------------------------------------------------------------
diff --git 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/SamlResponseCreator.java
 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/SamlResponseCreator.java
index 9ba1167..c0c0d22 100644
--- 
a/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/SamlResponseCreator.java
+++ 
b/services/idp/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/SamlResponseCreator.java
@@ -29,6 +29,7 @@ import org.apache.cxf.common.util.Base64Utility;
 import org.apache.cxf.fediz.core.exception.ProcessingException;
 import org.apache.cxf.fediz.core.exception.ProcessingException.TYPE;
 import org.apache.cxf.fediz.core.util.CertsUtils;
+import org.apache.cxf.fediz.service.idp.IdpConstants;
 import org.apache.cxf.fediz.service.idp.domain.Idp;
 import org.apache.cxf.fediz.service.idp.samlsso.SAML2CallbackHandler;
 import org.apache.cxf.fediz.service.idp.samlsso.SAML2PResponseComponentBuilder;
@@ -47,6 +48,8 @@ import org.apache.wss4j.common.util.DOM2Writer;
 import org.apache.wss4j.dom.WSConstants;
 import org.joda.time.DateTime;
 import org.opensaml.saml.saml2.core.Assertion;
+import org.opensaml.saml.saml2.core.AuthnRequest;
+import org.opensaml.saml.saml2.core.NameID;
 import org.opensaml.saml.saml2.core.Response;
 import org.opensaml.saml.saml2.core.Status;
 import org.slf4j.Logger;
@@ -80,7 +83,8 @@ public class SamlResponseCreator {
             
             String remoteAddr = 
WebUtils.getHttpServletRequest(context).getRemoteAddr();
             Assertion saml2Assertion = 
-                createSAML2Assertion(idp, wrapper, requestId, requestIssuer, 
remoteAddr, consumerURL);
+                createSAML2Assertion(context, idp, wrapper, requestId, 
requestIssuer, 
+                                     remoteAddr, consumerURL);
             
             Element response = createResponse(idp, requestId, saml2Assertion);
             return encodeResponse(response);
@@ -91,7 +95,7 @@ public class SamlResponseCreator {
         }
     }
     
-    private Assertion createSAML2Assertion(Idp idp, SamlAssertionWrapper 
receivedToken,
+    private Assertion createSAML2Assertion(RequestContext context, Idp idp, 
SamlAssertionWrapper receivedToken,
                                            String requestID, String 
requestIssuer, 
                                            String remoteAddr, String racs) 
throws Exception {
         // Create an AuthenticationAssertion
@@ -99,6 +103,20 @@ public class SamlResponseCreator {
         callbackHandler.setIssuer(idp.getRealm());
         callbackHandler.setSubject(receivedToken.getSaml2().getSubject());
         
+        // Test Subject against received Subject (if applicable)
+        AuthnRequest authnRequest = 
+            (AuthnRequest)WebUtils.getAttributeFromFlowScope(context, 
IdpConstants.SAML_AUTHN_REQUEST);
+        if (authnRequest.getSubject() != null && 
authnRequest.getSubject().getNameID() != null
+            && receivedToken.getSaml2().getSubject().getNameID() != null) {
+            NameID receivedNameId = authnRequest.getSubject().getNameID();
+            NameID issuedNameId = 
receivedToken.getSaml2().getSubject().getNameID();
+            if (!receivedNameId.getValue().equals(issuedNameId.getValue())) {
+                LOG.debug("Received NameID value of {} does not match issued 
value {}",
+                          receivedNameId.getValue(), issuedNameId.getValue());
+                throw new 
ProcessingException(ProcessingException.TYPE.INVALID_REQUEST);
+            }
+        }
+        
         // Subject Confirmation Data
         SubjectConfirmationDataBean subjectConfirmationData = new 
SubjectConfirmationDataBean();
         subjectConfirmationData.setAddress(remoteAddr);

Reply via email to