/// <summary> /// Handles the SOAP. /// </summary> /// <param name="context">The context.</param> /// <param name="inputStream">The input stream.</param> private void HandleSoap(HttpContext context, Stream inputStream) { var parser = new HttpArtifactBindingParser(inputStream); Logger.DebugFormat(TraceMessages.SOAPMessageParse, parser.SamlMessage.OuterXml); var builder = new HttpArtifactBindingBuilder(context); if (parser.IsArtifactResolve) { Logger.Debug(TraceMessages.ArtifactResolveReceived); var idp = RetrieveIDPConfiguration(parser.Issuer); if (!parser.CheckSamlMessageSignature(idp.Metadata.Keys)) { Logger.Error(ErrorMessages.ArtifactResolveSignatureInvalid); throw new Saml20Exception(ErrorMessages.ArtifactResolveSignatureInvalid); } builder.RespondToArtifactResolve(parser.ArtifactResolve); } else if (parser.IsArtifactResponse) { Logger.Debug(TraceMessages.ArtifactResolveReceived); var idp = RetrieveIDPConfiguration(parser.Issuer); if (!parser.CheckSamlMessageSignature(idp.Metadata.Keys)) { Logger.Error(ErrorMessages.ArtifactResponseSignatureInvalid); throw new Saml20Exception(ErrorMessages.ArtifactResponseSignatureInvalid); } var status = parser.ArtifactResponse.Status; if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success) { Logger.ErrorFormat(ErrorMessages.ArtifactResponseStatusCodeInvalid, status.StatusCode.Value); throw new Saml20Exception(string.Format(ErrorMessages.ArtifactResponseStatusCodeInvalid, status.StatusCode.Value)); } if (parser.ArtifactResponse.Any.LocalName == Response.ElementName) { if (!idp.AllowUnsolicitedResponses) { CheckReplayAttack(context, parser.ArtifactResponse.Any); } var responseStatus = GetStatusElement(parser.ArtifactResponse.Any); if (responseStatus.StatusCode.Value != Saml20Constants.StatusCodes.Success) { Logger.ErrorFormat(ErrorMessages.ArtifactResponseStatusCodeInvalid, responseStatus.StatusCode.Value); throw new Saml20Exception(string.Format(ErrorMessages.ArtifactResponseStatusCodeInvalid, responseStatus.StatusCode.Value)); } bool isEncrypted; var assertion = GetAssertion(parser.ArtifactResponse.Any, out isEncrypted); if (assertion == null) { Logger.Error(ErrorMessages.ArtifactResponseMissingAssertion); throw new Saml20Exception(ErrorMessages.ArtifactResponseMissingAssertion); } if (isEncrypted) { HandleEncryptedAssertion(context, assertion); } else { HandleAssertion(context, assertion); } } else { Logger.ErrorFormat(ErrorMessages.ArtifactResponseMissingResponse); throw new Saml20Exception(ErrorMessages.ArtifactResponseMissingResponse); } } else { Logger.ErrorFormat(ErrorMessages.SOAPMessageUnsupportedSamlMessage); throw new Saml20Exception(ErrorMessages.SOAPMessageUnsupportedSamlMessage); } }
/// <summary> /// Handles the SOAP message. /// </summary> /// <param name="context">The context.</param> /// <param name="inputStream">The input stream.</param> private void HandleSoap(HttpContext context, Stream inputStream) { var parser = new HttpArtifactBindingParser(inputStream); Logger.DebugFormat(TraceMessages.SOAPMessageParse, parser.SamlMessage.OuterXml); var builder = new HttpArtifactBindingBuilder(context); var config = Saml2Config.GetConfig(); var idp = RetrieveIDPConfiguration(parser.Issuer); if (parser.IsArtifactResolve) { Logger.DebugFormat(TraceMessages.ArtifactResolveReceived, parser.SamlMessage); if (!parser.CheckSamlMessageSignature(idp.Metadata.Keys)) { Logger.ErrorFormat(ErrorMessages.ArtifactResolveSignatureInvalid); throw new Saml20Exception(ErrorMessages.ArtifactResolveSignatureInvalid); } builder.RespondToArtifactResolve(parser.ArtifactResolve); } else if (parser.IsArtifactResponse) { Logger.DebugFormat(TraceMessages.ArtifactResponseReceived, parser.SamlMessage); if (!parser.CheckSamlMessageSignature(idp.Metadata.Keys)) { Logger.Error(ErrorMessages.ArtifactResponseSignatureInvalid); throw new Saml20Exception(ErrorMessages.ArtifactResponseSignatureInvalid); } var status = parser.ArtifactResponse.Status; if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success) { Logger.ErrorFormat(ErrorMessages.ArtifactResponseStatusCodeInvalid, status.StatusCode.Value); throw new Saml20Exception(string.Format(ErrorMessages.ArtifactResponseStatusCodeInvalid, status.StatusCode.Value)); } if (parser.ArtifactResponse.Any.LocalName == LogoutRequest.ElementName) { Logger.DebugFormat(TraceMessages.LogoutRequestReceived, parser.ArtifactResponse.Any.OuterXml); var req = Serialization.DeserializeFromXmlString<LogoutRequest>(parser.ArtifactResponse.Any.OuterXml); // Send logoutresponse via artifact var response = new Saml20LogoutResponse { Issuer = config.ServiceProvider.Id, StatusCode = Saml20Constants.StatusCodes.Success, InResponseTo = req.Id }; var endpoint = RetrieveIDPConfiguration(StateService.Get<string>(IdpLoginSessionKey)); var destination = DetermineEndpointConfiguration(BindingType.Redirect, endpoint.Endpoints.LogoutEndpoint, endpoint.Metadata.IDPSLOEndpoints); builder.RedirectFromLogout(destination, response); } else if (parser.ArtifactResponse.Any.LocalName == LogoutResponse.ElementName) { DoLogout(context); } else { Logger.ErrorFormat(ErrorMessages.ArtifactResponseMissingResponse); throw new Saml20Exception(ErrorMessages.ArtifactResponseMissingResponse); } } else if (parser.IsLogoutReqest) { Logger.DebugFormat(TraceMessages.LogoutRequestReceived, parser.SamlMessage.OuterXml); var req = parser.LogoutRequest; // Build the response object var response = new Saml20LogoutResponse { Issuer = config.ServiceProvider.Id, StatusCode = Saml20Constants.StatusCodes.Success, InResponseTo = req.Id }; // response.Destination = destination.Url; var doc = response.GetXml(); XmlSignatureUtils.SignDocument(doc, response.Id); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } builder.SendResponseMessage(doc.OuterXml); } else { Logger.ErrorFormat(ErrorMessages.SOAPMessageUnsupportedSamlMessage); throw new Saml20Exception(ErrorMessages.SOAPMessageUnsupportedSamlMessage); } }
/// <summary> /// Handles the SOAP. /// </summary> /// <param name="context">The context.</param> /// <param name="inputStream">The input stream.</param> public static void HandleSoap(HttpArtifactBindingBuilder builder, Stream inputStream, Saml2Configuration config, Action<Saml20Assertion> signonCallback, Func<string, object> getFromCache, Action<string, object, DateTime> setInCache, IDictionary<string, object> session) { var parser = new HttpArtifactBindingParser(inputStream); logger.DebugFormat(TraceMessages.SOAPMessageParse, parser.SamlMessage.OuterXml); if (parser.IsArtifactResolve) { logger.Debug(TraceMessages.ArtifactResolveReceived); var idp = IdpSelectionUtil.RetrieveIDPConfiguration(parser.Issuer, config); if (!parser.CheckSamlMessageSignature(idp.Metadata.Keys)) { logger.Error(ErrorMessages.ArtifactResolveSignatureInvalid); throw new Saml20Exception(ErrorMessages.ArtifactResolveSignatureInvalid); } builder.RespondToArtifactResolve(parser.ArtifactResolve, ((XmlDocument)getFromCache(parser.ArtifactResolve.Artifact)).DocumentElement); } else if (parser.IsArtifactResponse) { logger.Debug(TraceMessages.ArtifactResolveReceived); var idp = IdpSelectionUtil.RetrieveIDPConfiguration(parser.Issuer, config); if (!parser.CheckSamlMessageSignature(idp.Metadata.Keys)) { logger.Error(ErrorMessages.ArtifactResponseSignatureInvalid); throw new Saml20Exception(ErrorMessages.ArtifactResponseSignatureInvalid); } var status = parser.ArtifactResponse.Status; if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success) { logger.ErrorFormat(ErrorMessages.ArtifactResponseStatusCodeInvalid, status.StatusCode.Value); throw new Saml20Exception(string.Format(ErrorMessages.ArtifactResponseStatusCodeInvalid, status.StatusCode.Value)); } if (parser.ArtifactResponse.Any.LocalName == Response.ElementName) { Utility.CheckReplayAttack(parser.ArtifactResponse.Any, true, session); var responseStatus = Utility.GetStatusElement(parser.ArtifactResponse.Any); if (responseStatus.StatusCode.Value != Saml20Constants.StatusCodes.Success) { logger.ErrorFormat(ErrorMessages.ArtifactResponseStatusCodeInvalid, responseStatus.StatusCode.Value); throw new Saml20Exception(string.Format(ErrorMessages.ArtifactResponseStatusCodeInvalid, responseStatus.StatusCode.Value)); } bool isEncrypted; var assertion = Utility.GetAssertion(parser.ArtifactResponse.Any, out isEncrypted); if (assertion == null) { logger.Error(ErrorMessages.ArtifactResponseMissingAssertion); throw new Saml20Exception(ErrorMessages.ArtifactResponseMissingAssertion); } var samlAssertion = isEncrypted ? Utility.HandleEncryptedAssertion(assertion, config, getFromCache, setInCache) : Utility.HandleAssertion(assertion, config, getFromCache, setInCache); signonCallback(samlAssertion); } else { logger.ErrorFormat(ErrorMessages.ArtifactResponseMissingResponse); throw new Saml20Exception(ErrorMessages.ArtifactResponseMissingResponse); } } else { logger.ErrorFormat(ErrorMessages.SOAPMessageUnsupportedSamlMessage); throw new Saml20Exception(ErrorMessages.SOAPMessageUnsupportedSamlMessage); } }