public SamlTokenData GenerateDisplayName(SamlTokenData samlTokenData)
        {
            if (samlTokenData == null)
                return null;

            var displayName = samlTokenData.GetAttribute(DisplayNameAttribute);
            if (!string.IsNullOrEmpty(displayName))
                samlTokenData.CommonName = displayName;

            return samlTokenData;
        }
Example #2
0
        public virtual SamlTokenData GetSamlTokenData()
        {
            var samlUserLookup       = PluginManager.GetSingleton <ISamlUserLookup>();
            var dispalyNameGenerator = PluginManager.GetSingleton <ISamlDisplayNameGenerator>();
            var usernameGenerator    = PluginManager.GetSingleton <ISamlUsernameGenerator>();
            var samlTokenValidator   = PluginManager.GetSingleton <ISamlTokenDataValidator>();
            var apiUsers             = Apis.Get <IUsers>();

            //Extracts, validates and returns the assertion nodes from the current context samlResponse
            SecurityToken samlToken = GetAssertion();

            var samlTokenData = new SamlTokenData {
                Attributes = GetClaims(samlToken), ResponseDate = DateTime.Now, UserId = 0
            };


            samlTokenData.NameId = samlTokenData.ClientId = GetNameId(samlToken);
            samlTokenData.Email  = samlTokenData.GetAttribute(tokenProcessorConfiguration.EmailAttributeName, null);

            //fall back to a known claim if the nameid wasnt found in the saml token
            if (samlTokenData.ClientId == null)
            {
                samlTokenData.NameId = samlTokenData.ClientId = samlTokenData.UserName;
            }

            //see if we have a ISamlUserLookup to check for existing OauthLinks
            if (samlUserLookup != null && samlUserLookup.Enabled)
            {
                samlTokenData = samlUserLookup.GetUser(samlTokenData);
            }

            //check if we have a custom user name plugin and execute it now to populate the UserName attribue
            if (usernameGenerator != null && usernameGenerator.Enabled)
            {
                samlTokenData = usernameGenerator.GenerateUsername(samlTokenData);
            }
            else
            {
                samlTokenData.UserName = samlTokenData.GetAttribute(tokenProcessorConfiguration.UserNameAttributeName);
            }

            //check if we have a custom display name plugin and execute it now to populate the commonname attribue
            if (dispalyNameGenerator != null && dispalyNameGenerator.Enabled)
            {
                samlTokenData = dispalyNameGenerator.GenerateDisplayName(samlTokenData);
            }


            if (!samlTokenData.IsExistingUser()) //only run if the ISamlUserLookup didnt already give us the UserId
            {
                // Get the UserID
                int userID = 0;


                //look up the user by username.
                var user = apiUsers.Get(new UsersGetOptions()
                {
                    Username = samlTokenData.UserName
                });
                if (user != null && !user.HasErrors() && user.Id.HasValue)
                {
                    userID = user.Id.Value;
                }

                if (userID == 0 && tokenProcessorConfiguration.AllowTokenMatchingByEmailAddress)
                {
                    // look up the user by email address
                    user = apiUsers.Get(new UsersGetOptions()
                    {
                        Email = samlTokenData.Email.ToLower()
                    });
                    if (user != null && !user.HasErrors() && user.Id.HasValue)
                    {
                        userID = user.Id.Value;
                    }
                }

                if (userID > 0)
                {
                    samlTokenData.UserId = userID;
                }
            }

            if (samlTokenValidator != null && samlTokenValidator.Enabled)
            {
                samlTokenValidator.Validate(samlToken, samlTokenData);
            }

            samlTokenData.Validate();  //validate the token data before we make any db changes

            //Tuck this in context items for later use in this request
            SamlHelpers.SamlTokenDataContextItem = samlTokenData;

            return(samlTokenData);
        }
Example #3
0
        private static void UpdateSamlToken(SamlTokenData oAuthData)
        {
            string oAuthDataXml = SamlHelpers.ConvertToString(oAuthData);

            UpdateSamlToken(oAuthData.UserId, oAuthDataXml, oAuthData.ResponseDate, oAuthData.Email, oAuthData.NameId);
        }
Example #4
0
        public static void SaveSamlToken(SamlTokenData samlTokenData)
        {
            if (!samlTokenData.IsExistingUser()) throw new InvalidOperationException("The User Id must be greater than zero.");

            if (GetSamlTokenData(samlTokenData.UserId) == null)
                InsertSamlToken(samlTokenData);
            else
                UpdateSamlToken(samlTokenData);
        }
Example #5
0
        public void ProcessRequest(HttpContext context)
        {
            var samlPlugin = PluginManager.GetSingleton <SamlOAuthClient>();

            if (samlPlugin == null || !samlPlugin.Enabled)
            {
                throw new InvalidOperationException("Unable to load the SamlAuthentication plugin; saml logins are not supported in the current configuration");
            }

            if (SamlHelpers.IsSignInResponse)
            {
                //use httpcontextuser is set to true, so this code below will only ever fire if there is a HttpContextUser set
                SamlTokenData samlTokenData = null;

                if (!SamlHelpers.IsSignInResponse)
                {
                    throw new NotSupportedException("Unable to detect a saml response; please check your identity provider is configured properly");
                }

                //This call gets the saml token from the response, validates it and turns it into our internal class for use and storage
                samlTokenData = samlPlugin.TokenProcessor.GetSamlTokenData();

                if (samlTokenData == null)
                {
                    throw new InvalidOperationException("No valid saml token was decected, login failed");
                }

                if (samlTokenData.IsExistingUser())
                {
                    if (samlPlugin.PersistClaims)
                    {
                        SqlData.SaveSamlToken(samlTokenData);
                    }

                    //since new users will have oauth links auto created, we only run this code for existing users
                    var samlOAuthLinkManager = PluginManager.GetSingleton <ISamlOAuthLinkManager>();
                    if (samlOAuthLinkManager != null && samlOAuthLinkManager.Enabled)
                    {
                        // makes sure the user is not prompted to "link accounts" during the login form
                        //if there is no suitable entry in the te_OAuth_Links table
                        samlOAuthLinkManager.EnsureOAuthLink(samlTokenData);
                    }
                }

                //Store out the SAML Token Data in an encrypted cookie for use on the OAuth endpoint which requires a GET request
                //var tokenKey = samlTokenData.SaveToSecureCookie();
                //Store out the SAML Token Data in a table on the database for use in the OAuth endpoint which requires a GET request
                //This was added to prevent issues with cookie size - Tony Triguero 2/14/2019
                var tokenKey = samlTokenData.SaveTokenDataToDatabase();

                //build the oauth url based on the current url
                UriBuilder oAuthUrl = new UriBuilder(context.Request.Url);
                oAuthUrl.Path = oAuthUrl.Path.Replace("samlresponse/", string.Format("oauth", samlPlugin.ClientType)).Replace("samlresponse", string.Format("oauth", samlPlugin.ClientType));

                var queryString = HttpUtility.ParseQueryString(oAuthUrl.Query);

                queryString.Add("type", samlPlugin.ClientType);
                queryString.Add(SamlOAuthClient.oauthTokeyQuerystringKey, tokenKey.ToString());

                //Invitation Key
                string invitationKey = SamlHelpers.GetInvitationKey();
                if (!String.IsNullOrEmpty(invitationKey) && !queryString.ToString().ToLower().Contains("invitationkey="))
                {
                    queryString.Add(SamlHelpers.InvitationKeyParameterName, invitationKey);
                }

                //Return Url  (note this must return back to the login page, the actual final return url should be double encoded)
                string returnUrl = GetReturnUrl();
                if (!String.IsNullOrEmpty(returnUrl) && !queryString.ToString().ToLower().Contains("returnurl="))
                {
                    queryString.Add(SamlHelpers.ReturnUrlParameterName, string.Format("{0}&{1}={2}", samlPlugin.CallbackUrl, SamlHelpers.ReturnUrlParameterName, returnUrl)); //the ToString of the queryString object will properly encode the &ReturnUrl
                }
                oAuthUrl.Query = queryString.ToString();

                //Ensure HTTPS so our secure cookie can be read
                if (samlPlugin.SecureCookie || HttpContext.Current.Request.IsSecureConnection)
                {
                    oAuthUrl.Scheme = Uri.UriSchemeHttps;
                    oAuthUrl.Port   = -1; // default port for scheme
                }

                //redirect to the oauth endpoint
                var url = oAuthUrl.Uri.AbsoluteUri;
                context.Response.Redirect(oAuthUrl.Uri.AbsoluteUri);
                context.ApplicationInstance.CompleteRequest();
                context.Response.End();
            }
            else if (SamlHelpers.IsSignOutResponse)
            {
                var platformLogout = PluginManager.GetSingleton <IPlatformLogout>();
                if (platformLogout == null || !platformLogout.Enabled)
                {
                    throw new NotSupportedException("Unable to support WSFederation logouts without an appropriate IPlatformLogout plugin");
                }

                platformLogout.Logout();

                context.Response.Clear();
                context.Response.Buffer = true;
                // Read the original file from disk
                Stream myFileStream = EmbeddedResources.GetStream("Telligent.Services.SamlAuthenticationPlugin.Resources.Images.oauth.gif");
                long   FileSize     = myFileStream.Length;
                byte[] Buffer       = new byte[(int)FileSize];
                myFileStream.Read(Buffer, 0, (int)FileSize);
                myFileStream.Close();

                // Tell the browser stuff about the file
                context.Response.AddHeader("Content-Length", FileSize.ToString());
                context.Response.AddHeader("Content-Disposition", "inline; filename=oauth.gif");
                context.Response.ContentType = "image/gif";

                // Send the data to the browser
                context.Response.BinaryWrite(Buffer);
                context.ApplicationInstance.CompleteRequest();
                context.Response.End();
                return;
            }

            //if this is not a sign-in response, we should probably redirect to login.aspx
            throw new ArgumentException("The SAML token was not found in the HttpContext.Current.Request, please check the configuration and try again");
        }
Example #6
0
        public virtual SamlTokenData GetSamlTokenData()
        {
            var dispalyNameGenerator = PluginManager.GetSingleton<ISamlDisplayNameGenerator>();
            var usernameGenerator = PluginManager.GetSingleton<ISamlUsernameGenerator>();
            var samlTokenValidator = PluginManager.GetSingleton<ISamlTokenDataValidator>();

            //Extracts, validates and returns the assertion nodes from the current context samlResponse
            SecurityToken samlToken = GetAssertion();

            var samlTokenData = new SamlTokenData { Attributes = GetClaims(samlToken), ResponseDate = DateTime.Now };

            samlTokenData.NameId = samlToken.Id;
            samlTokenData.Email = samlTokenData.GetAttribute(tokenProcessorConfiguration.EmailAttributeName, null);

            if (usernameGenerator != null && usernameGenerator.Enabled)
                samlTokenData = usernameGenerator.GenerateUsername(samlTokenData);
            else
                samlTokenData.UserName = samlTokenData.GetAttribute(tokenProcessorConfiguration.UserNameAttributeName);

            //check if we have a custom display name plugin and execute it now to populate the commonname attribue
            if (dispalyNameGenerator != null && dispalyNameGenerator.Enabled)
                samlTokenData = dispalyNameGenerator.GenerateDisplayName(samlTokenData);

            // Get the UserID
            int userID = 0;

            //look up the user by username.
            var user = PublicApi.Users.Get(new UsersGetOptions() { Username = samlTokenData.UserName });
            if (user != null && !user.HasErrors() && user.Id.HasValue)
                userID = user.Id.Value;

            if (userID == 0 && tokenProcessorConfiguration.AllowTokenMatchingByEmailAddress)
            {
                // look up the user by email address
                user = PublicApi.Users.Get(new UsersGetOptions() { Email = samlTokenData.Email.ToLower() });
                if (user != null && !user.HasErrors() && user.Id.HasValue)
                    userID = user.Id.Value;
            }

            if (userID > 0)
                samlTokenData.UserId = userID;

            if (samlTokenValidator != null && samlTokenValidator.Enabled)
                samlTokenValidator.Validate(samlToken, samlTokenData);

            samlTokenData.Validate();  //validate the token data before we make any db changes

            //Tuck this in context items for later use in this request
            SamlHelpers.SamlTokenDataContextItem = samlTokenData;

            return samlTokenData;
        }