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);
