Ejemplo n.º 1
0
        private void HandleSOAP(HttpContext context, Stream inputStream)
        {
            Trace.TraceMethodCalled(GetType(), "HandleSOAP");

            HttpArtifactBindingParser  parser  = new HttpArtifactBindingParser(inputStream);
            HttpArtifactBindingBuilder builder = new HttpArtifactBindingBuilder(context);

            SAML20FederationConfig config = SAML20FederationConfig.GetConfig();

            IDPEndPoint idp = RetrieveIDPConfiguration(parser.Issuer);
            var         shaHashingAlgorithm = SignatureProviderFactory.ValidateShaHashingAlgorithm(idp.ShaHashingAlgorithm);

            AuditLogging.IdpId = idp.Id;


            if (parser.IsArtifactResolve())
            {
                Trace.TraceData(TraceEventType.Information, Tracing.ArtifactResolveIn);

                if (!parser.CheckSamlMessageSignature(idp.metadata.Keys))
                {
                    HandleError(context, "Invalid Saml message signature");
                    AuditLogging.logEntry(Direction.UNDEFINED, Operation.ARTIFACTRESOLVE, "Signature could not be verified", parser.SamlMessage);
                }
                AuditLogging.AssertionId = parser.ArtifactResolve.ID;
                AuditLogging.logEntry(Direction.IN, Operation.ARTIFACTRESOLVE, "", parser.SamlMessage);
                builder.RespondToArtifactResolve(idp, parser.ArtifactResolve);
            }
            else if (parser.IsArtifactResponse())
            {
                Trace.TraceData(TraceEventType.Information, Tracing.ArtifactResponseIn);

                Status status = parser.ArtifactResponse.Status;
                if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success)
                {
                    AuditLogging.logEntry(Direction.UNDEFINED, Operation.ARTIFACTRESOLVE, string.Format("Unexpected status code for artifact response: {0}, expected 'Success', msg: {1}", status.StatusCode.Value, parser.SamlMessage));
                    HandleError(context, status);
                    return;
                }

                if (parser.ArtifactResponse.Any.LocalName == LogoutRequest.ELEMENT_NAME)
                {
                    if (Trace.ShouldTrace(TraceEventType.Information))
                    {
                        Trace.TraceData(TraceEventType.Information, string.Format(Tracing.LogoutRequest, parser.ArtifactResponse.Any.OuterXml));
                    }

                    //Send logoutresponse via artifact
                    Saml20LogoutResponse response = new Saml20LogoutResponse();
                    response.Issuer = config.ServiceProvider.ID;
                    LogoutRequest req = Serialization.DeserializeFromXmlString <LogoutRequest>(parser.ArtifactResponse.Any.OuterXml);
                    response.StatusCode   = Saml20Constants.StatusCodes.Success;
                    response.InResponseTo = req.ID;
                    IDPEndPointElement destination =
                        DetermineEndpointConfiguration(SAMLBinding.REDIRECT, idp.SLOEndpoint, idp.metadata.SLOEndpoints());

                    builder.RedirectFromLogout(idp, destination, response);
                }
                else if (parser.ArtifactResponse.Any.LocalName == LogoutResponse.ELEMENT_NAME)
                {
                    DoLogout(context);
                }
                else
                {
                    AuditLogging.logEntry(Direction.UNDEFINED, Operation.ARTIFACTRESOLVE, string.Format("Unsupported payload message in ArtifactResponse: {0}, msg: {1}", parser.ArtifactResponse.Any.LocalName, parser.SamlMessage));
                    HandleError(context,
                                string.Format("Unsupported payload message in ArtifactResponse: {0}",
                                              parser.ArtifactResponse.Any.LocalName));
                }
            }
            else if (parser.IsLogoutReqest())
            {
                if (Trace.ShouldTrace(TraceEventType.Information))
                {
                    Trace.TraceData(TraceEventType.Information, string.Format(Tracing.LogoutRequest, parser.SamlMessage.OuterXml));
                }

                Saml20LogoutResponse response = new Saml20LogoutResponse();

                if (!parser.IsSigned())
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Signature not present in SOAP logout request, msg: " + parser.SamlMessage.OuterXml);
                    response.StatusCode = Saml20Constants.StatusCodes.RequestDenied;
                }

                if (idp.metadata == null)
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Cannot find metadata for IdP: " + parser.Issuer);
                    // Not able to process the request as we do not know the IdP.
                    response.StatusCode = Saml20Constants.StatusCodes.NoAvailableIDP;
                }
                else
                {
                    Saml20MetadataDocument metadata = idp.metadata;

                    if (!parser.CheckSignature(metadata.GetKeys(KeyTypes.signing)))
                    {
                        AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Request has been denied. Invalid signature SOAP logout, msg: " + parser.SamlMessage.OuterXml);
                        response.StatusCode = Saml20Constants.StatusCodes.RequestDenied;
                    }
                }

                if (parser.GetNameID() != null && !string.IsNullOrEmpty(parser.GetNameID().Value))
                {
                    DoSoapLogout(context, parser.GetNameID().Value);
                }
                else
                {
                    AuditLogging.logEntry(Direction.IN, Operation.LOGOUTREQUEST, "Request has been denied. No user ID was supplied in SOAP logout request, msg: " + parser.SamlMessage.OuterXml);
                    response.StatusCode = Saml20Constants.StatusCodes.NoAuthnContext;
                }

                LogoutRequest req = parser.LogoutRequest;

                //Build the response object
                response.Issuer       = config.ServiceProvider.ID;
                response.StatusCode   = Saml20Constants.StatusCodes.Success;
                response.InResponseTo = req.ID;
                XmlDocument doc = response.GetXml();
                var         signingCertificate = FederationConfig.GetConfig().SigningCertificate.GetCertificate();
                var         signatureProvider  = SignatureProviderFactory.CreateFromShaHashingAlgorithmName(shaHashingAlgorithm);
                signatureProvider.SignAssertion(doc, response.ID, signingCertificate);
                if (doc.FirstChild is XmlDeclaration)
                {
                    doc.RemoveChild(doc.FirstChild);
                }

                builder.SendResponseMessage(doc.OuterXml);
            }
            else
            {
                Status s = parser.GetStatus();
                if (s != null)
                {
                    HandleError(context, s);
                }
                else
                {
                    AuditLogging.logEntry(Direction.UNDEFINED, Operation.ARTIFACTRESOLVE, string.Format("Unsupported SamlMessage element: {0}, msg: {1}", parser.SamlMessageName, parser.SamlMessage));
                    HandleError(context, string.Format("Unsupported SamlMessage element: {0}", parser.SamlMessageName));
                }
            }
        }