// Process a successful SAML response. private void ProcessSuccessSAMLResponse(SAMLResponse samlResponse, string relayState) { //Processing successful SAML response // Load the decryption key. X509Certificate2 x509Certificate = GetSelerixCertificate(); // Extract the asserted identity from the SAML response. SAMLAssertion samlAssertion = null; if (samlResponse.GetAssertions().Count > 0) { samlAssertion = samlResponse.GetAssertions()[0]; } else if (samlResponse.GetEncryptedAssertions().Count > 0) { //"Decrypting assertion"); samlAssertion = samlResponse.GetEncryptedAssertions()[0].Decrypt(x509Certificate.PrivateKey, null); } else if (samlResponse.GetSignedAssertions().Count > 0) { samlAssertion = new SAMLAssertion(samlResponse.GetSignedAssertions()[0]); } else { throw new ArgumentException("No assertions in response"); } // Get the subject name identifier. string userName = null; if (samlAssertion.Subject.NameID != null) { userName = samlAssertion.Subject.NameID.NameIdentifier; } else if (samlAssertion.Subject.EncryptedID != null) { //"Decrypting ID"); NameID nameID = samlAssertion.Subject.EncryptedID.Decrypt(x509Certificate.PrivateKey, null); userName = nameID.NameIdentifier; } else { throw new ArgumentException("No name in subject"); } Dictionary <string, string> outputData = new Dictionary <string, string>(); foreach (AttributeStatement attributeStatement in samlAssertion.GetAttributeStatements()) { foreach (SAMLAttribute samlAttribute in attributeStatement.GetUnencryptedAttributes()) { foreach (AttributeValue attributeValue in samlAttribute.Values) { if (!outputData.ContainsKey(samlAttribute.Name)) { outputData.Add(samlAttribute.Name, attributeValue.ToString()); } else { outputData[samlAttribute.Name] = attributeValue.ToString(); } } } foreach (EncryptedAttribute encryptedAttribute in attributeStatement.GetEncryptedAttributes()) { SAMLAttribute samlAttribute = encryptedAttribute.Decrypt(x509Certificate.PrivateKey, null); foreach (AttributeValue attributeValue in samlAttribute.Values) { if (!outputData.ContainsKey(samlAttribute.Name)) { outputData.Add(samlAttribute.Name, attributeValue.ToString()); } else { outputData[samlAttribute.Name] = attributeValue.ToString(); } } } } // prevent the output of aspx page from being cached by the browser Response.AddHeader("Cache-Control", "no-cache"); Response.AddHeader("Pragma", "no-cache"); if (outputData.ContainsKey("Transmittal")) { Session["Transmittal"] = Selerix.Foundation.Data.SerializationHelper.DeserializeFromString(outputData["Transmittal"], typeof(Transmittal)); } else { Session["Transmittal"] = null; } Session["SAMLParameters"] = outputData; Response.Redirect("~/ShowTransmittal.aspx", false); //"Processed successful SAML response"); }
public ActionResult SingleSignOn(string attributes, string targetUrl, string partnerSP) { try { // Initiate single sign-on to the service provider (IdP-initiated SSO)] // by sending a SAML response containing a SAML assertion to the SP. // get the member id (was IWS number) from the database var member = Services.MemberService.GetByUsername(User.Identity.Name); Trace.TraceInformation(DateTime.Now.ToShortTimeString() + ":" + string.Format("---------------------USER '{0}' initiated the SSO---------------------", member.Username)); // Create a dictionary of attributes to add to the SAML assertion var attribs = new Dictionary <string, string>(); ///////////////////////////////////////////////////////////////////////// // SAML Parameter Configurations ///////////////////////////////////////////////////////////////////////// // Attributes for StatDoctors if (partnerSP == "StatDoctors") { string AccountUniqueContactId = member.GetValue("yNumber").ToString(); string AccountFamilyId = member.GetValue("yNumber").ToString(); if (AccountFamilyId.Length > 7) { AccountFamilyId = AccountFamilyId.Substring(0, 7); } string FamilyDependentId = member.GetValue("yNumber").ToString(); if (FamilyDependentId.Length > 7) { FamilyDependentId = FamilyDependentId.Substring(7, 2); } { // Create attribute list an populate with needed data var attrib = new Dictionary <string, string> { { "AccountUniqueContactId", AccountUniqueContactId }, { "AccountFamilyId", AccountFamilyId }, { "FamilyDependentId", FamilyDependentId }, { "PartnerId", "AC4134" }, { "PartnerAccountId", "" }, { "ReturnUrl", "" } }; // Send an IdP initiated SAML assertion SAMLIdentityProvider.InitiateSSO( Response, member.GetValue("yNumber").ToString(), attrib, "", partnerSP); } } // Attributes for US Script if (partnerSP == "USScript") { string yNumber = member.GetValue("yNumber").ToString(); if (yNumber.Length > 7) { yNumber = yNumber.Substring(0, 7); } var samlAttributes = new Dictionary <string, string> { { "urn:uss:saml:attrib::id", yNumber }, { "urn:uss:saml:attrib::firstname", member.GetValue("msFirstName").ToString() }, { "urn:uss:saml:attrib::lastname", member.GetValue("msLastName").ToString() }, { "urn:uss:saml:attrib::groupid", member.GetValue("groupId").ToString() }, { "urn:uss:saml:attrib::dateofbirth", Convert.ToDateTime(member.GetValue("birthday")).ToString("yyyy-MM-dd") }, { "urn:uss:saml:attrib::email", member.Email } }; PgpSAML20Assertion.GuideSSO(Response, partnerSP, String.Empty, samlAttributes); } // Attributes for MagnaCare if (partnerSP == "MagnaCare") { var samlAttributes = new Dictionary <string, string> { { "member:id", member.GetValue("yNumber").ToString() }, { "member:first_name", member.GetValue("msFirstName").ToString() }, { "member:last_name", member.GetValue("msLastName").ToString() }, { "member:product", member.GetValue("healthPlanName").ToString() } }; SAML20Assertion.GuideSSO(Response, partnerSP, member.GetValue("yNumber").ToString(), samlAttributes); } // Attributes for HealthX if (partnerSP == "https://secure.healthx.com/PublicService/SSO/AutoLogin.aspx" || partnerSP == "https://secure.healthx.com/PublicService/SSO/AutoLogin.aspx?mobile=1") { // Create attribute list an populate with needed data var attrib = new List <SAMLAttribute> { // Version 1 is constant value set by HealthX new SAMLAttribute("Version", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "Version", "xs:string", "1"), // This is the site ID and is redundant since it is in the Assertion consumer url. I added this for completeness new SAMLAttribute("ServiceId", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "ServiceID", "xs:string", "d99bfe58-3896-4eb6-9586-d2f9ae673052"), // This is the service ID and is redundant since it is in the Assertion consumer url. I added this for completeness new SAMLAttribute("SiteId", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "SiteId", "xs:string", "e6fa832c-fbd3-48c7-860f-e4f04b22bab7"), new SAMLAttribute("RelationshipCode", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "RelationshipCode", "xs:string", "18"), new SAMLAttribute("UserId", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "UserId", "xs:string", member.GetValue("yNumber").ToString().ToUpper()), new SAMLAttribute("MemberLastName", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "MemberLastName", "xs:string", member.GetValue("msLastName").ToString().ToUpper()), new SAMLAttribute("MemberFirstName", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "MemberFirstName", "xs:string", member.GetValue("msFirstName").ToString().ToUpper()), new SAMLAttribute("UserLastName", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "UserLastName", "xs:string", member.GetValue("msLastName").ToString().ToUpper()), new SAMLAttribute("UserFirstName", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "UserFirstName", "xs:string", member.GetValue("msFirstName").ToString().ToUpper()) }; // Nest a node named ServiceId in the RedirectInfo attribute // Add a serializer to allow the nesting of the serviceid attribute without it being url encoded if (!AttributeType.IsAttributeValueSerializerRegistered("RedirectInfo", null)) { AttributeType.RegisterAttributeValueSerializer("RedirectInfo", null, new XmlAttributeValueSerializer()); } // Add Redirect Info xml var xmlRedirectInfo = new XmlDocument { PreserveWhitespace = true }; xmlRedirectInfo.LoadXml(targetUrl); var attrRedirectInfo = new SAMLAttribute("RedirectInfo", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic", "RedirectInfo"); attrRedirectInfo.Values.Add(new AttributeValue(xmlRedirectInfo.DocumentElement)); attrib.Add(attrRedirectInfo); // Send an IdP initiated SAML assertion SAMLIdentityProvider.InitiateSSO( Response, member.GetValue("yNumber").ToString(), attrib.ToArray(), "", partnerSP); } // Attributes for Morneau Shapell if (partnerSP == "SBCSystems") { // Replace the template variables in the url if (targetUrl.IndexOf("<%PLANID%>") != -1) { targetUrl = targetUrl.Replace("<%PLANID%>", member.GetValue("healthplanid").ToString()); } // Replace "initialEnrollment" with "specialEnrollmentSelect" if outside of 11/15-3/31 if (targetUrl.Contains("initialEnrollment") && !IsInInitialEnrollmentPeriod()) { targetUrl = targetUrl.Replace("initialEnrollment", "specialEnrollmentSelect"); } // Send an IdP initiated SAML assertion SAMLIdentityProvider.InitiateSSO( Response, member.GetValue("memberId").ToString(), attribs, targetUrl, partnerSP); } // Add the response to the ViewBag so we can access it on the front end if we need to ViewBag.Response = Response; TempData["response"] = Response; // Return an empty response since we wait for the SAML consumer to send us the requested page return(new EmptyResult()); } catch (Exception ex) { // Create an error message with sufficient info to contact the user string additionalInfo = "SSO Error for user " + User.Identity.Name + ". Partner: " + partnerSP + ". TargetUrl: " + targetUrl + "."; // Add the error message to the log4net output log4net.GlobalContext.Properties["additionalInfo"] = additionalInfo; // Log the error logger.Error("Unable to use SSO", ex); return(new EmptyResult()); } }
public async Task <ActionResult> SSOService() { var logger = log4net.LogManager.GetLogger("SAMLController"); logger.Info("SSOService() - Single sign-on service entered"); var pendingSessionKey = Session[ssoPendingSessionKey]; logger.Debug("Session[ssoPendingSessionKey] = " + ((pendingSessionKey == null) ? "null" : pendingSessionKey.ToString())); // Either an authn request has been received or login has just completed in response to a previous authn request. // The SSO pending session flag is false if an authn request is expected. Otherwise, it is true if // a login has just completed and control is being returned to this page. bool ssoPending = pendingSessionKey != null && (bool)Session[ssoPendingSessionKey] == true; logger.Debug("ssoPending = " + ssoPending.ToString()); logger.Debug("User.Identity.IsAuthenticated = " + User.Identity.IsAuthenticated.ToString()); if (!(ssoPending && User.Identity.IsAuthenticated)) { string partnerSP = null; // Receive the authn request from the service provider (SP-initiated SSO). SAMLIdentityProvider.ReceiveSSO(Request, out partnerSP); logger.Debug("partnerSP = " + partnerSP); // If the user isn't logged in at the identity provider, force the user to login. if (!User.Identity.IsAuthenticated) { Session[ssoPendingSessionKey] = true; logger.Info("User not authenticated, redirecting to login page()"); FormsAuthentication.RedirectToLoginPage(); return(new EmptyResult()); } } Session[ssoPendingSessionKey] = null; // The user is logged in at the identity provider. // Respond to the authn request by sending a SAML response containing a SAML assertion to the SP. // Use the configured or logged in user name as the user name to send to the service provider (SP). // Include some user attributes. var userName = WebConfigurationManager.AppSettings[AppSettings.SubjectName]; var identity = (ClaimsIdentity)User.Identity; if (string.IsNullOrEmpty(userName)) { var bid = identity.FindFirst("bid_id"); if (bid == null) { logger.Info("bid_id claim not found, redirecting to login page"); FormsAuthentication.RedirectToLoginPage(); return(new EmptyResult()); } userName = bid.Value; var firstName = identity.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"); var lastName = identity.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"); logger.Info("Username obtained from BankID : " + userName); logger.Info("Firstname from BankID : " + ((firstName == null) ? "<not provided>" : firstName.Value)); logger.Info("Lastname from BankID : " + ((lastName == null) ? "<not provided>" : lastName.Value)); var iseSettings = Utility.Configuration.Settings.IseServer; var iseUri = new UriBuilder("https", iseSettings.ServerIP.ToString(), 9060); var developerConnection = new CiscoISE.ISEConnection(iseUri.Uri, iseSettings.ApiUsername, iseSettings.ApiPassword); var portals = await CiscoISE.Portals.Get(developerConnection); if (portals == null) { throw new Exception("Could not access ISE to enumerate portals"); } logger.Debug("Retrieved portals from the Cisco ISE server using the API account"); // TODO : Research whether this is the best way to get the sponsor portal. var sponsorPortal = portals.Where(x => x.Name == "Sponsor Portal (default)").FirstOrDefault(); if (sponsorPortal == null) { throw new Exception("Could not access ISE to find GUID for Sponsor Portal (default)"); } logger.Debug("Sponsor portal found on ISE server : " + sponsorPortal.Name); var sponsorConnection = new CiscoISE.ISEConnection(iseUri.Uri, iseSettings.SponsorPortalUsername, iseSettings.SponsorPortalPassword); logger.Debug("Finding an existing guest user with username : "******"Retrieved user " + userName + " from ISE server\n" + JsonConvert.SerializeObject(guestUser)); } else { logger.Info("Existing user (" + userName + ") not found, attempt to create a new one"); logger.Debug("Getting GuestTypes from ISE server"); // TODO : Catch errors on connecting to the API var guestTypes = await CiscoISE.GuestTypes.Get(developerConnection); if (guestTypes == null) { // TODO : Provide a better method of handling API issues throw new Exception("Failed to get a list of GuestTypes from Cisco ISE"); } // TODO : Provide a configuration option to allow specific guest types to be // chosen based on how the user is logging in. var guestType = guestTypes.FirstOrDefault(); if (guestType == null) { // TODO : Provide a better method of dealing with there not being any guest types throw new Exception("There appears to be no guest types configured in Cisco ISE"); } logger.Info("Using first guest type in the list : " + guestType.Name); logger.Debug("Getting list of guest locations from the ISE server"); // TODO : Catch exceptions on guest locations var guestLocations = await CiscoISE.GuestLocations.Get(developerConnection); if (guestLocations == null) { // TODO : Provide a better method of handling API issues throw new Exception("Failed to obtain a list of guest locations from Cisco ISE"); } // TODO : Provide a configuration option to allow specific guest locations to be // chosen based on where the user is logging in var guestLocation = guestLocations.FirstOrDefault(); if (guestLocation == null) { // TODO : Provide a better method of handling API issues throw new Exception("ISE does not appear to have any guest locations configured"); } logger.Info("Using first guest location from the list " + guestLocation.Name); //var randomPassword = Membership.GeneratePassword(16, 4); var randomPassword = CiscoISE.Utility.PasswordGenerator.GenerateStrongGuestPassword(); // TODO : Consider removing this from the code. Though, the password is not used anywhere, it could be a "alarm" during a code audit logger.Info("Automatically generated a password for the new user (" + randomPassword + ")"); // TODO : Add configuration settings to specify the duration which a guest account is valid var validFrom = DateTime.Now; var validUntil = validFrom.AddHours(4); guestUser = new GuestUserViewModel { GuestType = guestType.Name, // TODO : File "bug" with Cisco over name referencing instead of ID PortalId = sponsorPortal.Id.ToString(), GuestInfo = new CiscoISE.GuestInfoViewModel { Username = userName, Password = randomPassword, FirstName = firstName == null ? "<unknown>" : firstName.Value, LastName = lastName == null ? "<unknown>" : lastName.Value, Enabled = true }, GuestAccessInfo = new GuestAccessInfoViewModel { ValidDays = 1, FromDate = validFrom, ToDate = validUntil, Location = guestLocation.Name // TODO : File "bug" with Cisco over name reference instead of ID } }; logger.Debug("guestUser = "******"Creating new guest user"); var created = await CiscoISE.GuestUsers.Create( sponsorConnection, guestUser ); logger.Info(created ? "Guest user created" : "Guest user failed to be created"); if (!created) { throw new Exception("Failed to create new guest user, cannot continue login process"); } } } var ClaimToAttributes = new [] { new { claimType = Microsoft.IdentityModel.Protocols.OpenIdConnectParameterNames.AccessToken, samlAttributeName = "bidAccessToken" }, new { claimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth", samlAttributeName = "dateofbirth" }, new { claimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", samlAttributeName = "givenname" }, new { claimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname", samlAttributeName = "surname" }, new { claimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", samlAttributeName = "name" } }; logger.Info("Appending attributes to SAML assertion"); var samlAttributes = new List <SAMLAttribute>(); foreach (var claimToAttribute in ClaimToAttributes) { var claim = identity.FindFirst(claimToAttribute.claimType); if (claim != null) { var attribute = new SAMLAttribute( claimToAttribute.samlAttributeName, SAMLIdentifiers.AttributeNameFormats.Unspecified, null, "xs:string", claim.Value ); samlAttributes.Add(attribute); } } ComponentSpace.SAML2.SAMLController.TraceLevel = System.Diagnostics.TraceLevel.Verbose; logger.Info("Sending SSO to SAML service provider"); SAMLIdentityProvider.SendSSO(Response, userName, samlAttributes.ToArray()); return(new EmptyResult()); }
public ActionResult SingleSignOn(string attributes, string targetUrl, string partnerSP) { try { // Initiate single sign-on to the service provider (IdP-initiated SSO)] // by sending a SAML response containing a SAML assertion to the SP. // get the member id (was IWS number) from the database var member = Services.MemberService.GetByUsername(User.Identity.Name); Trace.TraceInformation(DateTime.Now.ToShortTimeString() + ":" + string.Format("---------------------USER '{0}' initiated the SSO---------------------", member.Username)); // Create a dictionary of attributes to add to the SAML assertion var attribs = new Dictionary<string, string>(); ///////////////////////////////////////////////////////////////////////// // SAML Parameter Configurations ///////////////////////////////////////////////////////////////////////// // Attributes for StatDoctors if (partnerSP == "StatDoctors") { string AccountUniqueContactId = member.GetValue("yNumber").ToString(); string AccountFamilyId = member.GetValue("yNumber").ToString(); if (AccountFamilyId.Length > 7) AccountFamilyId = AccountFamilyId.Substring(0, 7); string FamilyDependentId = member.GetValue("yNumber").ToString(); if (FamilyDependentId.Length > 7) FamilyDependentId = FamilyDependentId.Substring(7, 2); { // Create attribute list an populate with needed data var attrib = new Dictionary<string, string> { {"AccountUniqueContactId", AccountUniqueContactId}, {"AccountFamilyId", AccountFamilyId}, {"FamilyDependentId", FamilyDependentId}, {"PartnerId", "AC4134"}, {"PartnerAccountId", ""}, {"ReturnUrl", ""} }; // Send an IdP initiated SAML assertion SAMLIdentityProvider.InitiateSSO( Response, member.GetValue("yNumber").ToString(), attrib, "", partnerSP); } } // Attributes for US Script if (partnerSP == "USScript") { string yNumber = member.GetValue("yNumber").ToString(); if (yNumber.Length > 7) yNumber = yNumber.Substring(0, 7); var samlAttributes = new Dictionary<string, string> { {"urn:uss:saml:attrib::id", yNumber}, {"urn:uss:saml:attrib::firstname", member.GetValue("msFirstName").ToString()}, {"urn:uss:saml:attrib::lastname", member.GetValue("msLastName").ToString()}, {"urn:uss:saml:attrib::groupid", member.GetValue("groupId").ToString()}, {"urn:uss:saml:attrib::dateofbirth", Convert.ToDateTime(member.GetValue("birthday")).ToString("yyyy-MM-dd")}, {"urn:uss:saml:attrib::email", member.Email} }; PgpSAML20Assertion.GuideSSO(Response, partnerSP, String.Empty, samlAttributes); } // Attributes for MagnaCare if (partnerSP == "MagnaCare") { var samlAttributes = new Dictionary<string, string> { {"member:id", member.GetValue("yNumber").ToString()}, {"member:first_name", member.GetValue("msFirstName").ToString()}, {"member:last_name", member.GetValue("msLastName").ToString()}, {"member:product", member.GetValue("healthPlanName").ToString()} }; SAML20Assertion.GuideSSO(Response, partnerSP, member.GetValue("yNumber").ToString(), samlAttributes); } // Attributes for HealthX if (partnerSP == "https://secure.healthx.com/PublicService/SSO/AutoLogin.aspx" || partnerSP == "https://secure.healthx.com/PublicService/SSO/AutoLogin.aspx?mobile=1") { // Create attribute list an populate with needed data var attrib = new List<SAMLAttribute> { // Version 1 is constant value set by HealthX new SAMLAttribute("Version", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "Version", "xs:string", "1"), // This is the site ID and is redundant since it is in the Assertion consumer url. I added this for completeness new SAMLAttribute("ServiceId", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "ServiceID", "xs:string", "d99bfe58-3896-4eb6-9586-d2f9ae673052"), // This is the service ID and is redundant since it is in the Assertion consumer url. I added this for completeness new SAMLAttribute("SiteId", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "SiteId", "xs:string", "e6fa832c-fbd3-48c7-860f-e4f04b22bab7"), new SAMLAttribute("RelationshipCode", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "RelationshipCode", "xs:string", "18"), new SAMLAttribute("UserId", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "UserId", "xs:string", member.GetValue("yNumber").ToString().ToUpper()), new SAMLAttribute("MemberLastName", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "MemberLastName", "xs:string", member.GetValue("msLastName").ToString().ToUpper()), new SAMLAttribute("MemberFirstName", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "MemberFirstName", "xs:string", member.GetValue("msFirstName").ToString().ToUpper()), new SAMLAttribute("UserLastName", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "UserLastName", "xs:string", member.GetValue("msLastName").ToString().ToUpper()), new SAMLAttribute("UserFirstName", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", "UserFirstName", "xs:string", member.GetValue("msFirstName").ToString().ToUpper()) }; // Nest a node named ServiceId in the RedirectInfo attribute // Add a serializer to allow the nesting of the serviceid attribute without it being url encoded if (!AttributeType.IsAttributeValueSerializerRegistered("RedirectInfo", null)) AttributeType.RegisterAttributeValueSerializer("RedirectInfo", null, new XmlAttributeValueSerializer()); // Add Redirect Info xml var xmlRedirectInfo = new XmlDocument { PreserveWhitespace = true }; xmlRedirectInfo.LoadXml(targetUrl); var attrRedirectInfo = new SAMLAttribute("RedirectInfo", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic", "RedirectInfo"); attrRedirectInfo.Values.Add(new AttributeValue(xmlRedirectInfo.DocumentElement)); attrib.Add(attrRedirectInfo); // Send an IdP initiated SAML assertion SAMLIdentityProvider.InitiateSSO( Response, member.GetValue("yNumber").ToString(), attrib.ToArray(), "", partnerSP); } // Attributes for Morneau Shapell if (partnerSP == "SBCSystems") { // Replace the template variables in the url if (targetUrl.IndexOf("<%PLANID%>") != -1) targetUrl = targetUrl.Replace("<%PLANID%>", member.GetValue("healthplanid").ToString()); // Replace "initialEnrollment" with "specialEnrollmentSelect" if outside of 11/15-3/31 if (targetUrl.Contains("initialEnrollment") && !IsInInitialEnrollmentPeriod()) { targetUrl = targetUrl.Replace("initialEnrollment", "specialEnrollmentSelect"); } // Send an IdP initiated SAML assertion SAMLIdentityProvider.InitiateSSO( Response, member.GetValue("memberId").ToString(), attribs, targetUrl, partnerSP); } // Add the response to the ViewBag so we can access it on the front end if we need to ViewBag.Response = Response; TempData["response"] = Response; // Return an empty response since we wait for the SAML consumer to send us the requested page return new EmptyResult(); } catch (Exception ex) { // Create an error message with sufficient info to contact the user string additionalInfo = "SSO Error for user " + User.Identity.Name + ". Partner: " + partnerSP + ". TargetUrl: " + targetUrl + "."; // Add the error message to the log4net output log4net.GlobalContext.Properties["additionalInfo"] = additionalInfo; // Log the error logger.Error("Unable to use SSO", ex); return new EmptyResult(); } }