Beispiel #1
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);
        }
Beispiel #2
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);
        }
Beispiel #3
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());
        }
Beispiel #4
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());
        }
        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"));
            }
        }
Beispiel #6
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());
        }
Beispiel #7
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());
        }