Example #1
0
        protected void Page_Load(object sender, EventArgs e)
        {
            // Receive the single logout request or response.
            // If a request is received then single logout is being initiated by the service provider.
            // If a response is received then this is in response to single logout having been initiated by the identity provider.
            bool   isRequest    = false;
            bool   hasCompleted = false;
            string logoutReason = null;
            string partnerSP    = null;
            string relayState   = null;

            SAMLIdentityProvider.ReceiveSLO(Request, Response, out isRequest, out hasCompleted, out logoutReason, out partnerSP, out relayState);

            if (isRequest)
            {
                // Logout locally.
                FormsAuthentication.SignOut();

                // Respond to the SP-initiated SLO request indicating successful logout.
                SAMLIdentityProvider.SendSLO(Response, null);
            }
            else
            {
                if (hasCompleted)
                {
                    // IdP-initiated SLO has completed.
                    Response.Redirect("~/");
                }
            }
        }
Example #2
0
        protected void ssoLinkButton_Click(object sender, EventArgs e)
        {
            // Initiate single sign-on to the service provider (IdP-initiated SSO)
            // 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.
            // If no target URL is specified the SP should display its default page.
            string partnerSP = WebConfigurationManager.AppSettings[AppSettings.PartnerSP];
            string targetUrl = WebConfigurationManager.AppSettings[AppSettings.TargetUrl];

            string userName = WebConfigurationManager.AppSettings[AppSettings.SubjectName];

            if (string.IsNullOrEmpty(userName))
            {
                userName = User.Identity.Name;
            }

            IDictionary <string, string> attributes = new Dictionary <string, string>();

            foreach (string key in WebConfigurationManager.AppSettings.Keys)
            {
                if (key.StartsWith(AppSettings.Attribute))
                {
                    attributes[key.Substring(AppSettings.Attribute.Length + 1)] = WebConfigurationManager.AppSettings[key];
                }
            }

            SAMLIdentityProvider.InitiateSSO(
                Response,
                userName,
                attributes,
                targetUrl,
                partnerSP);
        }
Example #3
0
        public ActionResult SLOService()
        {
            var isRequest    = false;
            var hasCompleted = false;
            var logoutReason = default(string);
            var partnerSP    = default(string);

            SAMLIdentityProvider.ReceiveSLO(
                Request,
                Response,
                out isRequest,
                out hasCompleted,
                out logoutReason,
                out partnerSP);

            // If this is a request, then the logout was initiated by a partner SP.
            if (isRequest)
            {
                Response.ForgetUserIdentity();
                SAMLIdentityProvider.SendSLO(Response, null);
            }
            else if (hasCompleted)
            {
                // IdP-initiated SLO has completed.
                Response.ForgetUserIdentity();
                Response.Redirect("~/");
            }

            return(new EmptyResult());
        }
Example #4
0
        public ActionResult SLOService()
        {
            // Receive the single logout request or response.
            // If a request is received then single logout is being initiated by the service provider.
            // If a response is received then this is in response to single logout having been initiated by the identity provider.
            bool   isRequest    = false;
            bool   hasCompleted = false;
            string logoutReason = null;
            string partnerSP    = null;

            SAMLIdentityProvider.ReceiveSLO(Request, Response, out isRequest, out hasCompleted, out logoutReason, out partnerSP);

            if (isRequest)
            {
                // Logout locally.
                FormsAuthentication.SignOut();

                // Respond to the SP-initiated SLO request indicating successful logout.
                SAMLIdentityProvider.SendSLO(Response, null);
            }
            else
            {
                if (hasCompleted)
                {
                    // IdP-initiated SLO has completed.
                    Response.Redirect("~/");
                }
            }

            return(new EmptyResult());
        }
Example #5
0
        protected void ssoLinkButton_Click(object sender, EventArgs e)
        {
            string partnerSP = WebConfigurationManager.AppSettings[AppSettings.PartnerSP];
            string targetUrl = WebConfigurationManager.AppSettings[AppSettings.TargetUrl];

            string userName = WebConfigurationManager.AppSettings[AppSettings.SubjectName];

            if (string.IsNullOrEmpty(userName))
            {
                userName = User.Identity.Name;
            }

            IDictionary <string, string> attributes = new Dictionary <string, string>();

            foreach (string key in WebConfigurationManager.AppSettings.Keys)
            {
                if (key.StartsWith(AppSettings.Attribute))
                {
                    attributes[key.Substring(AppSettings.Attribute.Length + 1)] = WebConfigurationManager.AppSettings[key];
                }
            }

            SAMLIdentityProvider.InitiateSSO(
                Response,
                userName,
                attributes,
                targetUrl,
                partnerSP);
        }
Example #6
0
        protected void Page_Load(object sender, EventArgs e)
        {
            // Receive an authn request from an enhanced client or proxy (ECP).
            string partnerSP = null;

            SAMLIdentityProvider.ReceiveSSO(Request, out partnerSP);

            // In this example, the user's credentials are assumed to be included in the HTTP authorization header.
            // The application should authenticate the user against some user registry.
            // In this example, the credentials are assumed to be valid and no check is made.
            string userName = null;
            string password = null;

            HttpBasicAuthentication.GetAuthorizationHeader(Request, out userName, out password);

            // 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.
            if (!string.IsNullOrEmpty(WebConfigurationManager.AppSettings[AppSettings.SubjectName]))
            {
                userName = WebConfigurationManager.AppSettings[AppSettings.SubjectName];
            }

            IDictionary <string, string> attributes = new Dictionary <string, string>();

            foreach (string key in WebConfigurationManager.AppSettings.Keys)
            {
                if (key.StartsWith(AppSettings.Attribute))
                {
                    attributes[key.Substring(AppSettings.Attribute.Length + 1)] = WebConfigurationManager.AppSettings[key];
                }
            }

            SAMLIdentityProvider.SendSSO(Response, userName, attributes);
        }
Example #7
0
        private static void ReceiveAuthnRequest(XmlElement xmlElement)
        {
            SAML.HttpContext = new SAMLHttpContext();
            SAMLHttpRequest samlHttpRequest = new SAMLHttpRequest(xmlElement, null, null, null);

            string partnerSP = null;

            SAMLIdentityProvider.ReceiveSSO(samlHttpRequest, out partnerSP);

            Console.WriteLine("Partner SP: {0}", partnerSP);
        }
Example #8
0
        public ActionResult SSOService()
        {
            // This method is called either by an SP request for authentication or,
            // as part of that process, by the local AccountController Login method.
            // Once we've received the request, the Session will be set with a temporary
            // flag to indicate that we have already retrieved the SP authentication
            // request.
            var ssoReceived = Session.GetValue(SSOReceivedSessionKey, false);

            var partnerSP = default(string);

            if (!ssoReceived)
            {
                SAMLIdentityProvider.ReceiveSSO(Request, out partnerSP);
                Session[SSOReceivedSessionKey] = true;
                Session[PartnerSPSessionKey]   = partnerSP;
            }
            else
            {
                partnerSP = Session.GetValue(PartnerSPSessionKey);
            }

            // If a user isn't logged in locally, get them logged in.  We'll return to
            // this method via the returnUrl.
            UpdateUser();
            if (!User.Identity.IsAuthenticated)
            {
                return(RedirectToAction("LogIn", "Account", new { returnUrl = Request.Url.AbsolutePath }));
            }

            // If we are here, then the user is logged in locally, we've received
            // an external request for authentication from an SP, and we need to send a
            // SAML response.
            Session[SSOReceivedSessionKey] = null;
            Session[PartnerSPSessionKey]   = null;

            var user       = Database.Find <UserDoc>(u => u.Id == (User as UserModel).Id);
            var attributes = new Dictionary <string, string>();

            foreach (var attr in user.Attributes.Where(a => a.PartnerSP == partnerSP))
            {
                attributes[attr.Name] = attr.Value;
            }

            SAMLIdentityProvider.SendSSO(
                Response,
                User.Identity.Name,
                attributes as IDictionary <string, string>);

            return(new EmptyResult());
        }
Example #9
0
        public ActionResult SSOService()
        {
            // 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 = Session[ssoPendingSessionKey] != null && (bool)Session[ssoPendingSessionKey] == true;

            if (!(ssoPending && User.Identity.IsAuthenticated))
            {
                string partnerSP = null;

                // Receive the authn request from the service provider (SP-initiated SSO).
                SAMLIdentityProvider.ReceiveSSO(Request, out partnerSP);

                // If the user isn't logged in at the identity provider, force the user to login.
                if (!User.Identity.IsAuthenticated)
                {
                    Session[ssoPendingSessionKey] = true;
                    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.
            string userName = WebConfigurationManager.AppSettings[AppSettings.SubjectName];

            if (string.IsNullOrEmpty(userName))
            {
                userName = User.Identity.Name;
            }

            IDictionary <string, string> attributes = new Dictionary <string, string>();

            foreach (string key in WebConfigurationManager.AppSettings.Keys)
            {
                if (key.StartsWith(AppSettings.Attribute))
                {
                    attributes[key.Substring(AppSettings.Attribute.Length + 1)] = WebConfigurationManager.AppSettings[key];
                }
            }

            SAMLIdentityProvider.SendSSO(Response, userName, attributes);

            return(new EmptyResult());
        }
Example #10
0
        public ActionResult LogOff()
        {
            // Logout locally.
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);

            if (SAMLIdentityProvider.CanSLO())
            {
                // Request logout at the service providers.
                SAMLIdentityProvider.InitiateSLO(Response, null, null);

                return(new EmptyResult());
            }

            return(RedirectToAction("Index", "Home"));
        }
Example #11
0
        public ActionResult Logout()
        {
            // Logout locally.
            FormsAuthentication.SignOut();

            if (SAMLIdentityProvider.CanSLO())
            {
                // Request logout at the service providers.
                SAMLIdentityProvider.InitiateSLO(Response, null, null);

                return(new EmptyResult());
            }

            return(RedirectToAction("Index", "Home"));
        }
Example #12
0
        protected void logoutButton_Click(object sender, EventArgs e)
        {
            // Logout locally.
            FormsAuthentication.SignOut();

            if (SAMLIdentityProvider.CanSLO())
            {
                // Request logout at the service providers.
                SAMLIdentityProvider.InitiateSLO(Response, null, null);
            }
            else
            {
                FormsAuthentication.RedirectToLoginPage();
            }
        }
Example #13
0
        private void CompleteSingleSignOn()
        {
            // Get the name of the logged in user.
            var userName = User.Identity.Name;

            // For demonstration purposes, include some claims.
            var attributes = new Dictionary <string, string>();

            foreach (var claim in ((ClaimsIdentity)User.Identity).Claims)
            {
                attributes[claim.Type] = claim.Value;
            }

            // 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.
            SAMLIdentityProvider.SendSSO(Response, userName, attributes);
        }
        public ActionResult SingleSignOnService()
        {
            // Receive the authn request from the service provider (SP-initiated SSO).
            SAMLIdentityProvider.ReceiveSSO(Request, out var partnerName);

            // If the user is logged in at the identity provider, complete SSO immediately.
            // Otherwise have the user login before completing SSO.
            if (User.Identity.IsAuthenticated)
            {
                CompleteSingleSignOn();

                return(new EmptyResult());
            }
            else
            {
                return(RedirectToAction("SingleSignOnServiceCompletion"));
            }
        }
Example #15
0
        public ActionResult SingleLogoutService()
        {
            // Receive the single logout request or response.
            // If a request is received then single logout is being initiated by a partner service provider.
            // If a response is received then this is in response to single logout having been initiated by the identity provider.
            bool   isRequest;
            bool   hasCompleted;
            string logoutReason;
            string partnerName;
            string relayState;

            SAMLIdentityProvider.ReceiveSLO(
                Request,
                Response,
                out isRequest,
                out hasCompleted,
                out logoutReason,
                out partnerName,
                out relayState);

            if (isRequest)
            {
                // Logout locally.
                HttpContext.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);

                // Respond to the SP-initiated SLO request indicating successful logout.
                SAMLIdentityProvider.SendSLO(Response, null);
            }
            else
            {
                if (hasCompleted)
                {
                    // IdP-initiated SLO has completed.
                    if (!string.IsNullOrEmpty(relayState) && Url.IsLocalUrl(relayState))
                    {
                        return(Redirect(relayState));
                    }

                    return(RedirectToAction("Index", "Home"));
                }
            }

            return(new EmptyResult());
        }
Example #16
0
        private static void ReceiveLogoutMessageFromServiceProvider(XmlElement xmlElement)
        {
            SAML.HttpContext = new SAMLHttpContext();
            SAMLHttpRequest  samlHttpRequest  = new SAMLHttpRequest(xmlElement, null, null, null);
            SAMLHttpResponse samlHttpResponse = new SAMLHttpResponse();

            bool   isRequest    = false;
            bool   hasCompleted = false;
            string logoutReason = null;
            string partnerSP    = null;
            string relayState   = null;

            SAMLIdentityProvider.ReceiveSLO(samlHttpRequest, samlHttpResponse, out isRequest, out hasCompleted, out logoutReason, out partnerSP, out relayState);

            Console.WriteLine("Logout request: {0}", isRequest);
            Console.WriteLine("Logout completed: {0}", hasCompleted);
            Console.WriteLine("Logout reason: {0}", logoutReason);
            Console.WriteLine("Partner SP: {0}", partnerSP);
        }
Example #17
0
        public ActionResult SLOService()
        {
            // Receive the single logout request or response.
            // If a request is received then single logout is being initiated by the service provider.
            // If a response is received then this is in response to single logout having been initiated by the identity provider.
            bool   isRequest    = false;
            bool   hasCompleted = false;
            string logoutReason = null;
            string partnerSP    = null;
            string relayState   = null;

            SAMLIdentityProvider.ReceiveSLO(Request, Response, out isRequest, out hasCompleted, out logoutReason, out partnerSP, out relayState);

            if (isRequest)
            {
                // Logout locally.
                FormsAuthentication.SignOut();

                string logoutPath = UtilityMethods.ReadConfigValue("pathLogout");
                _log.Debug("Calling " + logoutPath);
                string logoutResponse = WebServiceRequester.MakeWebPageCall(logoutPath);
                this.HttpContext.CleanupCookies();


                // Respond to the SP-initiated SLO request indicating successful logout.
                SAMLIdentityProvider.SendSLO(Response, null);
            }
            else
            {
                if (hasCompleted)
                {
                    // IdP-initiated SLO has completed.
                    Response.Redirect("~/");
                }
            }

            return(new EmptyResult());
        }
Example #18
0
        public ActionResult SingleSignOn()
        {
            // Initiate single sign-on to the service provider (IdP-initiated SSO)
            // 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.
            // If a target URL is specified the SP should display this page once SSO completes.
            string partnerSP = WebConfigurationManager.AppSettings[AppSettings.PartnerSP];
            string targetUrl = WebConfigurationManager.AppSettings[AppSettings.TargetUrl];

            string userName = WebConfigurationManager.AppSettings[AppSettings.SubjectName];

            if (string.IsNullOrEmpty(userName))
            {
                userName = User.Identity.Name;
            }

            IDictionary <string, string> attributes = new Dictionary <string, string>();

            foreach (string key in WebConfigurationManager.AppSettings.Keys)
            {
                if (key.StartsWith(AppSettings.Attribute))
                {
                    attributes[key.Substring(AppSettings.Attribute.Length + 1)] = WebConfigurationManager.AppSettings[key];
                }
            }

            SAMLIdentityProvider.InitiateSSO(
                Response,
                userName,
                attributes,
                targetUrl,
                partnerSP);

            return(new EmptyResult());
        }
Example #19
0
        public ActionResult IdpSloService()
        {
            bool   isRequest, hasCompleted;
            string logoutReason, partnerSp;

            SAMLIdentityProvider.ReceiveSLO(Request, Response, out isRequest, out hasCompleted, out logoutReason, out partnerSp);

            if (isRequest)
            {
                SessionHelper.Set(SourceDomainSessionKey, null);
                SessionHelper.Set(UserSessionKey, null);

                SAMLIdentityProvider.SendSLO(Response, null);
            }
            else
            {
                if (hasCompleted)
                {
                    Response.Redirect("~/");
                }
            }

            return(new EmptyResult());
        }
Example #20
0
        public ActionResult InitiateSingleSignOn()
        {
            // Get the name of the logged in user.
            var userName = User.Identity.Name;

            // For demonstration purposes only, include all the claims as SAML attributes.
            // To include a specific claim: ((ClaimsIdentity) User.Identity).FindFirst(ClaimTypes.GivenName).
            var attributes = new Dictionary <string, string>();

            foreach (var claim in ((ClaimsIdentity)User.Identity).Claims)
            {
                attributes[claim.Type] = claim.Value;
            }

            var partnerName = WebConfigurationManager.AppSettings["PartnerName"];
            var relayState  = WebConfigurationManager.AppSettings["TargetUrl"];

            // Initiate single sign-on to the service provider (IdP-initiated SSO)
            // by sending a SAML response containing a SAML assertion to the SP.
            // The optional relay state normally specifies the target URL once SSO completes.
            SAMLIdentityProvider.InitiateSSO(Response, userName, attributes, relayState, partnerName);

            return(new EmptyResult());
        }
Example #21
0
        public ActionResult SSOService()
        {
            // Either an authn request has been received or login has just completed in response to a previous authn request.

            _log.Debug("SSO Service Begin");
            string partnerSP   = null;
            string myCurrentSP = SAMLIdentityProvider.GetPartnerPendingResponse();
            Dictionary <string, object> paramDictionary = new Dictionary <string, object> {
                { "optionalParam", Request.Params["optionalParam"] }
            };

            if (Request.Form.AllKeys.Contains("SAMLRequest") || (Request.QueryString.AllKeys.Contains("SAMLRequest") && (Request.QueryString.AllKeys.Contains("RelayState") || Request.QueryString.AllKeys.Contains("Signature"))))
            {
                // Receive the authn request from the service provider (SP-initiated SSO).
                _log.Debug("Calling ReceiveSSO");
                SAMLIdentityProvider.ReceiveSSO(Request, out partnerSP);
                myCurrentSP = SAMLIdentityProvider.GetPartnerPendingResponse();
                _log.Debug("Received SSO from " + partnerSP);
            }

            // If the user isn't logged in at the identity provider, force the user to login.
            if (!User.Identity.IsAuthenticated)
            {
                _log.Debug("Redirecting to login");
                FormsAuthentication.RedirectToLoginPage();
                return(new EmptyResult());
            }


            // 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.
            string userName = WebConfigurationManager.AppSettings[AppSettings.SubjectName];
            IDictionary <string, string> attributes = new Dictionary <string, string>();

            if (string.IsNullOrEmpty(userName))
            {
                try
                {
                    string memberPath = UtilityMethods.ReadConfigValue("pathGetMember");
                    _log.Debug("Calling " + memberPath);
                    string          memberResponse = WebServiceRequester.MakeServiceCall(memberPath);
                    SiteMemberModel memberModel    = UtilityMethods.DeserializeResponse <SiteMemberModel>(memberResponse);
                    userName = memberModel.MembershipId.ToString();
                    bool getsAdditionalValues = true;

                    //determine which SP, and populate the respective member attributes
                    myCurrentSP = SAMLIdentityProvider.GetPartnerPendingResponse();
                    //Connection with remote Learner
                    if (myCurrentSP.Contains("oldmoney.remote-learner.net") || myCurrentSP.Contains("saltcourses.saltmoney.org"))
                    {
                        attributes = AddRemoteLearnerAttributes(attributes, memberModel);

                        //Setup (create/update) user in Courses
                        MoodleUser mu = new MoodleUser(memberModel);
                        mu.SetupUser();
                    }

                    if (myCurrentSP.Contains("sso.online.tableau.com"))
                    {
                        attributes = AddTableauAttributes(attributes, memberModel);
                    }

                    if (myCurrentSP.Contains("community.saltmoney.org"))
                    {
                        String optionalParam = (String)paramDictionary["optionalParam"];
                        attributes = AddJiveAttributes(attributes, memberModel, optionalParam);
                    }

                    _log.Debug("Calling AddSSOCoreAttributes");
                    attributes = AddSSOCoreAttributes(attributes, memberModel, myCurrentSP, getsAdditionalValues);
                    _log.Debug("Returned from  AddSSOCoreAttributes with " + attributes.Count() + " Attributes");
                }
                catch (Exception ex)
                {
                    _log.Error(ex);
                    throw ex;
                }
            }
            try {
                _log.Debug("Calling SendSSO for " + userName);
                SAMLIdentityProvider.SendSSO(Response, userName, attributes);
            }
            catch (Exception ex)
            {
                _log.Error(ex);
                throw ex;
            }
            return(new EmptyResult());
        }
Example #22
0
        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());
            }
        }
Example #23
0
        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());
        }