protected void ProcessChallenges(dynamic challengeCollection, bool doSecondChallenge = false)
    {
        //We should clear our dropdown list every time to ensure we are starting with a clean list.
        MFAChallenge_DropDownList.Items.Clear();

        // We need to satisfy one of each challenge collection:
        SortedList <string, string> items = new SortedList <string, string>();

        //If doSecondChallenge is true we will change the challenge set array to the second set. Otherwise we will use the first Challenge set
        int challengeSet = 0;

        if (doSecondChallenge)
        {
            challengeSet = 1;
        }

        //The first step for the drop down list is to populate a SortedList with our MFA mechanisms
        for (int mechIdx = 0; mechIdx < challengeCollection[challengeSet]["Mechanisms"].Count; mechIdx++)
        {
            string mechValue = ConvertDicToString(challengeCollection[challengeSet]["Mechanisms"][mechIdx]);
            items.Add(UiDrivenLogin.MechToDescription(challengeCollection[challengeSet]["Mechanisms"][mechIdx]), mechValue);
        }

        //The second step for the drop down list is to bind the SortedList to our dropdown element
        try
        {
            MFAChallenge_DropDownList.DataTextField  = "Key";
            MFAChallenge_DropDownList.DataValueField = "Value";
            MFAChallenge_DropDownList.DataSource     = items;
            MFAChallenge_DropDownList.DataBind();
        }
        catch (Exception ex)
        {
            //There was an error
            Login_Div.Visible    = false;
            FailureText.Text     = ex.InnerException.ToString();
            ErrorMessage.Visible = true;
        }

        StartAuthentication_Next_Button.Visible   = false;
        AdvanceAuthentication_Next_Button.Visible = true;
        Form.DefaultButton = AdvanceAuthentication_Next_Button.UniqueID;
        MFAChallenge_DropDownList.Visible       = true;
        MFAChallenge_DropDownList_Label.Visible = true;

        Dictionary <string, string> mech = MFAChallenge_DropDownList.SelectedItem.Value.TrimEnd(';').Split(';').ToDictionary(item => item.Split('=')[0], item => item.Split('=')[1]);

        //If our first mechanism in our dropdown has a text answer type we should show our MFA answer text box.
        if (mech["AnswerType"] == "Text")
        {
            MFAAnswer_Label.Text      = UiDrivenLogin.MechToPrompt(mech);
            MFAAnswer_Label.Visible   = true;
            MFAAnswer_Textbox.Visible = true;
        }
        else if (mech["AnswerType"] != "Text" && mech["AnswerType"] != "StartTextOob")
        {
            //Set the Loading text for polling
            MFALoad_Label.Text = MFAAnswer_Label.Text = UiDrivenLogin.MechToPrompt(mech);
        }
    }
    //Called every time the MFA Dropdown is changed by the user.
    protected void MFAChallenge_SelectedIndexChanged(object sender, EventArgs e)
    {
        //Show text answer UI elements if selected MFA mechanism requires text input from the user.
        Dictionary <string, string> mech = MFAChallenge_DropDownList.SelectedItem.Value.TrimEnd(';').Split(';').ToDictionary(item => item.Split('=')[0], item => item.Split('=')[1]);

        if (mech["AnswerType"] == "Text")
        {
            MFAAnswer_Label.Text      = UiDrivenLogin.MechToPrompt(mech);
            MFAAnswer_Label.Visible   = true;
            MFAAnswer_Textbox.Visible = true;
        }
        else
        {
            MFAAnswer_Label.Visible   = false;
            MFAAnswer_Textbox.Visible = false;
        }

        //make sure that the MFA Label is modified to match selected mech.
        if (mech["AnswerType"] != "StartOob")
        {
            //Set the Loading text for polling
            MFALoad_Label.Text = "";
        }
        else
        {
            MFALoad_Label.Text = MFAAnswer_Label.Text = UiDrivenLogin.MechToPrompt(mech);
        }
    }
    protected void StartAuthentication(object sender, EventArgs e)
    {
        RestClient authenticationClient = UiDrivenLogin.Authenticate(TenantUrl, UserName_TextBox.Text + DefaultDomain);

        if (authenticationClient != null)
        {
            ProcessChallenges(authenticationClient.ChallengeCollection);
            Session["AuthenticaitonClient"] = authenticationClient;

            UserName_TextBox.Enabled       = false;
            SocialLogin_Div.Visible        = false;
            Register_HyperLink_Div.Visible = false;

            if (authenticationClient.AllowPasswordReset)
            {
                ForgotPass_Button.Visible = true;
            }

            RememberMe_Div.Visible   = true;
            StartOver_Button.Visible = true;
        }
        else
        {
            //There was an error
            Login_Div.Visible    = false;
            FailureText.Text     = "There was an unexpected error. Please contact your system administrator. Click here to <a href=\"Login.aspx\">start over.</a>";
            ErrorMessage.Visible = true;
        }
    }
Example #4
0
    protected void Submit_UserModify(object sender, EventArgs e)
    {
        //Create a new client to store authentication
        RestClient authenticationClient = UiDrivenLogin.Authenticate(TenantUrl, AdminServiceAccount);
        //Parse result challenge list. This is a service account so we can assume the results will be password and that there will only be one result.
        Dictionary <string, dynamic> mech = authenticationClient.ChallengeCollection[0]["Mechanisms"][0];

        //Login for service account is assumed to only require password and no MFA.
        if (mech["AnswerType"] == "Text")
        {
            //Call advance authentication with our service account credentials
            UiDrivenLogin.AdvanceForMech(authenticationClient, authenticationClient.TenantId, authenticationClient.SessionId, true, mech, null, AdminServicePass);
        }
        //Something other then text was returned which indicates that the service account is not set up correctly.
        else
        {
            FailureText.Text     = "The service account is not set up correctly. It should only require a password an no MFA.";
            ErrorMessage.Visible = true;

            UserInfo_div.Visible        = false;
            MyAccount_Start_div.Visible = false;
        }

        //Create a new userManagementClient and pass our authenticated rest client from our login call.
        UserManagement userManagementClient = new UserManagement(authenticationClient);
        CDUser         cUser = new CDUser();

        cUser.Name         = LoginName.Text + "@" + Alias_DropDownList.SelectedItem.ToString();
        cUser.ID           = UserUUID.Text;
        cUser.DisplayName  = DisplayName.Text;
        cUser.Mail         = Email.Text;
        cUser.OfficeNumber = OfficeNumber.Text;
        cUser.MobileNumber = MobileNumber.Text;
        cUser.HomeNumber   = HomeNumber.Text;

        Dictionary <string, dynamic> modifyUserResult = userManagementClient.ChangeUser(cUser, InEverybodyRole.Checked);

        if (modifyUserResult["success"])
        {
            SuccessText.Text       = "User " + LoginName.Text + " was successfully modified.";
            SuccessMessage.Visible = true;

            //hide unneeded elements.
            UserInfo_div.Visible        = false;
            MyAccount_Start_div.Visible = false;
        }
        else
        {
            FailureText.Text     = "There was an error modifying the user: "******"Message"];
            ErrorMessage.Visible = true;

            //hide unneeded elements.
            UserInfo_div.Visible        = false;
            MyAccount_Start_div.Visible = false;
        }
    }
    protected void Continue_Social_Login(string strExtIdpAuthChallengeState)
    {
        RestClient authenticationClient = (RestClient)Session["AuthenticaitonClient"];
        Dictionary <string, dynamic> socialLoginResult = UiDrivenLogin.ContinueSocialAuth(authenticationClient, strExtIdpAuthChallengeState);

        authenticationClient.TenantId  = socialLoginResult["Result"]["TenantId"];
        authenticationClient.SessionId = socialLoginResult["Result"]["SessionId"];

        if (socialLoginResult["success"].ToString() == "True")
        {
            if (socialLoginResult["Result"]["Summary"] == "LoginSuccess")
            {
                //Login Complete
                Login_Div.Visible = false;
                Session["OTP"]    = socialLoginResult["Result"]["Auth"];

                Session["isLoggedIn"] = "true";

                UserManagement userManagementClient = new UserManagement(authenticationClient);

                //Check if user is admin
                Dictionary <string, dynamic> getUserInfo = userManagementClient.GetUserInfo();

                if (getUserInfo["Result"]["IsSysAdmin"])
                {
                    Session["isAdmin"] = "true";
                }

                if (Request.QueryString["redirect"] != null)
                {
                    Server.Transfer(Request.QueryString["redirect"], true);
                }
                else
                {
                    Server.Transfer("Default.aspx", true);
                }
            }
            else if (socialLoginResult["Result"]["Summary"] == "NewPackage")
            {
                authenticationClient.ChallengeCollection = socialLoginResult["Result"]["Challenges"];
                Session["AuthenticaitonClient"]          = authenticationClient;
                ProcessChallenges(socialLoginResult["Result"]["Challenges"]);
                UserName_Label.Visible   = false;
                UserName_TextBox.Visible = false;
            }
        }
        else
        {
            //There was an error
            Login_Div.Visible    = false;
            FailureText.Text     = socialLoginResult["Message"] + " Click here to <a href=\"Login.aspx\">start over.</a>";
            ErrorMessage.Visible = true;
        }
    }
    protected void StartTextOob_TimerTick(object sender, EventArgs e)
    {
        //Start polling to see if user completed MFA remotely
        RestClient authenticationClient = (RestClient)Session["AuthenticaitonClient"];
        Dictionary <string, dynamic> resultsDictionary = UiDrivenLogin.AdvanceForMech(authenticationClient, authenticationClient.TenantId, authenticationClient.SessionId, RememberMe.Checked, null, MFAChallenge_DropDownList.SelectedItem.Value, "PollOnce", true);

        //MFA was successful. We need to process the results to determine what should happen next.
        if (resultsDictionary["Result"]["Summary"] == "StartNextChallenge" || resultsDictionary["Result"]["Summary"] == "LoginSuccess" || resultsDictionary["Result"]["Summary"] == "NewPackage")
        {
            StartTextOob_Timer.Enabled = false;
            ProcessResults(resultsDictionary);
        }
        //If there is an error we need to stop polling
        else if (!resultsDictionary["success"])
        {
            StartTextOob_Timer.Enabled = false;

            Login_Div.Visible    = false;
            FailureText.Text     = resultsDictionary["Message"] + " Click here to <a href=\"Login.aspx\">start over.</a>";
            ErrorMessage.Visible = true;
        }
    }
    //**IMPROVMENT REQUIRED: Move Social authenticaiton methods to API LIB
    protected void SocialLogin(object sender, EventArgs e)
    {
        string strIDPName = "";

        if (sender.Equals(SocialLogin_FB_Button))
        {
            strIDPName = "Facebook";
        }
        else if (sender.Equals(SocialLogin_Google_Button))
        {
            strIDPName = "Google";
        }
        else if (sender.Equals(SocialLogin_LinkedIn_Button))
        {
            strIDPName = "LinkedIn";
        }
        else if (sender.Equals(SocialLogin_Microsoft_Button))
        {
            strIDPName = "Microsoft";
        }

        RestClient authenticationClient = UiDrivenLogin.StartSocialAuth(TenantUrl, strIDPName, Request.Url.ToString());

        if (authenticationClient != null)
        {
            Session["AuthenticaitonClient"] = authenticationClient;
            Response.Redirect(authenticationClient.SocialIdpRedirectUrl);
        }
        else
        {
            //There was an error
            Login_Div.Visible       = false;
            SocialLogin_Div.Visible = false;
            FailureText.Text        = "There was an unexpected error. Please contact your system administrator. Click here to <a href=\"Login.aspx\">start over.</a>";
            ErrorMessage.Visible    = true;
        }
    }
Example #8
0
    protected void GetUserInfo(object sender, EventArgs e)
    {
        Alias_DropDownList.Items.Clear();
        //Create a new client to store authentication
        RestClient serviceAuthenticationClient = UiDrivenLogin.Authenticate(TenantUrl, AdminServiceAccount);
        //Parse result challenge list. This is a service account so we can assume the results will be password and that there will only be one result.
        Dictionary <string, dynamic> mech = serviceAuthenticationClient.ChallengeCollection[0]["Mechanisms"][0];

        //Login for service account is assumed to only require password and no MFA.
        if (mech["AnswerType"] == "Text")
        {
            //Call advance authentication with our service account credentials
            UiDrivenLogin.AdvanceForMech(serviceAuthenticationClient, serviceAuthenticationClient.TenantId, serviceAuthenticationClient.SessionId, true, mech, null, AdminServicePass);
        }
        //Something other then text was returned which indicates that the service account is not set up correctly.
        else
        {
            FailureText.Text     = "The service account is not set up correctly. It should only require a password an no MFA.";
            ErrorMessage.Visible = true;

            UserInfo_div.Visible        = false;
            MyAccount_Start_div.Visible = false;
        }

        //Pull authentication client from session
        RestClient authenticationClient = (RestClient)Session["AuthenticaitonClient"];

        //Create a new userManagementClient and pass our authenticated rest client from our login call.
        UserManagement userManagementClient        = new UserManagement(authenticationClient);
        UserManagement serviceUserManagementClient = new UserManagement(serviceAuthenticationClient);

        Dictionary <string, dynamic> getAliases = userManagementClient.GetAliasesForTenant();

        //Get a list of all tenant Aliases
        int iCount = 0;

        foreach (var alias in getAliases["Result"]["Results"])
        {
            Alias_DropDownList.Items.Insert(0, new ListItem(alias["Row"]["ID"], iCount.ToString()));
            iCount++;
        }

        //Get User Info
        Dictionary <string, dynamic> getUser       = userManagementClient.GetUser();
        Dictionary <string, dynamic> getUserResult = getUser["Result"];
        //Get User UUID
        Dictionary <string, dynamic> queryResult = serviceUserManagementClient.Query(@"select ID from cduser where Name ='" + getUserResult["Name"] + "'");

        int queryCount = queryResult["Count"];

        if (queryCount == 1)
        {
            //split the username and domain name. add user name into LoginName text box and select the correct domain in the alias dropdown.
            string   s        = getUserResult["Name"];
            string[] userName = s.Split('@');

            Alias_DropDownList.Items.FindByText(userName[1]).Selected = true;


            //populate user info
            LoginName.Text = userName[0];
            UserUUID.Text  = queryResult["Results"][0]["Row"]["ID"];
            Email.Text     = getUserResult["Mail"];

            //check that optional attributes are populated
            if (getUserResult.ContainsKey("DisplayName"))
            {
                DisplayName.Text = getUserResult["DisplayName"];
            }

            if (getUserResult.ContainsKey("OfficeNumber"))
            {
                OfficeNumber.Text = getUserResult["OfficeNumber"];
            }

            if (getUserResult.ContainsKey("MobileNumber"))
            {
                MobileNumber.Text = getUserResult["MobileNumber"];
            }

            if (getUserResult.ContainsKey("HomeNumber"))
            {
                HomeNumber.Text = getUserResult["HomeNumber"];
            }

            if (getUserResult.ContainsKey("InEverybodyRole"))
            {
                InEverybodyRole.Checked = getUserResult["InEverybodyRole"];
            }



            //show/hide elements
            UserInfo_div.Visible = true;
        }
        else
        {
            FailureText.Text = "There was an error getting the logged in users ID.";

            //hide unneeded elements.
            ErrorMessage.Visible        = true;
            UserInfo_div.Visible        = false;
            MyAccount_Start_div.Visible = false;
        }
    }
    //Called when the user selects an MFA type from the MFA DropDown and presses next.
    protected void AdvanceAuthentication(object sender, EventArgs e)
    {
        Dictionary <string, string> mech = MFAChallenge_DropDownList.SelectedItem.Value.TrimEnd(';').Split(';').ToDictionary(item => item.Split('=')[0], item => item.Split('=')[1]);
        RestClient authenticationClient  = (RestClient)Session["AuthenticaitonClient"];

        Dictionary <string, dynamic> resultsDictionary = new Dictionary <string, dynamic>();

        if (sender.Equals(ForgotPass_Button))
        {
            resultsDictionary             = UiDrivenLogin.AdvanceForMech(authenticationClient, authenticationClient.TenantId, authenticationClient.SessionId, RememberMe.Checked, null, null, null, false, true);
            MFAAnswer_Label.Visible       = false;
            MFAAnswer_Textbox.Visible     = false;
            RememberMe_Div.Visible        = false;
            ForgotPass_Button_Div.Visible = false;
        }
        else
        {
            //If the mechanism is StartTextOob we need to allow the user to answer via text and poll at the same time.
            if (mech["AnswerType"] == "StartTextOob")
            {
                if (StartTextOob_Timer.Enabled) //We have already called AdvanceAuthentication once and are calling it again using the MFA Answer Text Box submit button.
                {
                    resultsDictionary = UiDrivenLogin.AdvanceForMech(authenticationClient, authenticationClient.TenantId, authenticationClient.SessionId, RememberMe.Checked, null, MFAChallenge_DropDownList.SelectedItem.Value, MFAAnswer_Textbox.Text, true);
                }
                else //This is the first time calling AdvanceAuthenticaiton and we need to start polling and turn on our TimerTick while also displaying the MFA Answer Text Box for user input.
                {
                    resultsDictionary = UiDrivenLogin.AdvanceForMech(authenticationClient, authenticationClient.TenantId, authenticationClient.SessionId, RememberMe.Checked, null, MFAChallenge_DropDownList.SelectedItem.Value);

                    MFAAnswer_Label.Text       = UiDrivenLogin.MechToPrompt(mech);
                    MFAAnswer_Label.Visible    = true;
                    MFAAnswer_Textbox.Visible  = true;
                    StartTextOob_Timer.Enabled = true; //Used to poll again every tick while waiting for user input in the form.
                }
            }
            else
            {
                //User input is required for standard text mechanisms
                if (mech["AnswerType"] == "Text")
                {
                    resultsDictionary = UiDrivenLogin.AdvanceForMech(authenticationClient, authenticationClient.TenantId, authenticationClient.SessionId, RememberMe.Checked, null, MFAChallenge_DropDownList.SelectedItem.Value, MFAAnswer_Textbox.Text);
                }
                //No user input required for polling mechanisms
                else
                {
                    resultsDictionary  = UiDrivenLogin.AdvanceForMech(authenticationClient, authenticationClient.TenantId, authenticationClient.SessionId, RememberMe.Checked, null, MFAChallenge_DropDownList.SelectedItem.Value);
                    MFALoad_Label.Text = ""; //Change the loading text back to default
                }

                MFAAnswer_Label.Visible   = false;
                MFAAnswer_Textbox.Visible = false;
            }
        }

        //Check results
        if (resultsDictionary["success"])
        {
            MFAChallenge_DropDownList.Visible       = false;
            MFAChallenge_DropDownList_Label.Visible = false;

            //MFA was successful. We need to process the results to determine what should happen next.
            if (resultsDictionary["Result"]["Summary"] == "StartNextChallenge" || resultsDictionary["Result"]["Summary"] == "LoginSuccess" || resultsDictionary["Result"]["Summary"] == "NewPackage")
            {
                StartTextOob_Timer.Enabled = false; //Turn off timer so that we are not polling in the background for StartTextOob
                ProcessResults(resultsDictionary);
            }
            //If the summary is OobPending this means that StartTextOob has returned pending and we need to stop and wait. If any other results are present there is an error.
            else if (resultsDictionary["Result"]["Summary"] != "OobPending")
            {
                //There was an error
                Login_Div.Visible    = false;
                FailureText.Text     = "There was an unexpected error. Please contact your system administrator. Click here to <a href=\"Login.aspx\">start over.</a>";
                ErrorMessage.Visible = true;
            }
        }
        else
        {
            //There was an error
            Login_Div.Visible    = false;
            FailureText.Text     = resultsDictionary["Message"] + " Click here to <a href=\"Login.aspx\">start over.</a>";
            ErrorMessage.Visible = true;
        }
    }
    protected void Submit_Registration(object sender, EventArgs e)
    {
        //Create a new client to store authentication
        RestClient authenticationClient = UiDrivenLogin.Authenticate(TenantUrl, AdminServiceAccount);
        //Parse result challenge list. This is a service account so we can assume the results will be password and that there will only be one result.
        Dictionary <string, dynamic> mech = authenticationClient.ChallengeCollection[0]["Mechanisms"][0];

        //Login for service account is assumed to only require password and no MFA.
        if (mech["AnswerType"] == "Text")
        {
            //Call advance authentication with our service account credentials
            UiDrivenLogin.AdvanceForMech(authenticationClient, authenticationClient.TenantId, authenticationClient.SessionId, true, mech, null, AdminServicePass);
        }
        //Something other then text was returned which indicates that the service account is not set up correctly.
        else
        {
            FailureText.Text     = "The service account is not set up correctly. It should only require a password an no MFA.";
            ErrorMessage.Visible = true;

            Registration.Visible = false; //Hide our registration form.
        }

        //Set up dictionary to hold our create user results.
        Dictionary <string, dynamic> createUserResult = null;

        //Check if the passwords match
        if (Password.Text == Confirm_Password.Text)
        {
            //Create a new userManagementClient and pass our authenticated rest client from our login call.
            UserManagement userManagementClient = new UserManagement(authenticationClient);

            //Call the create user api and pass the contents of our registration form.
            CDUser cUser = new CDUser();
            cUser.Name         = LoginName.Text + DefaultDomain;
            cUser.Mail         = Email.Text;
            cUser.DisplayName  = DisplayName.Text;
            cUser.Password     = Password.Text;
            cUser.OfficeNumber = OfficeNumber.Text;
            cUser.MobileNumber = MobileNumber.Text;
            cUser.HomeNumber   = HomeNumber.Text;

            createUserResult = userManagementClient.CreateUser(cUser, false, false, false, false, true);
        }
        //The passwords did not match
        else
        {
            FailureText.Text     = "Password and Confirm Password do not match. Please refresh the page and try again.";
            ErrorMessage.Visible = true;

            Registration.Visible = false; //Hide our registration form.
        }

        //Check if the create user call was successful and present the results if it was.
        if (createUserResult["success"])
        {
            SuccessText.Text       = "User " + LoginName.Text + " was successfully created. Please here to <a href=\"Login.aspx\">login.";
            SuccessMessage.Visible = true;

            Registration.Visible = false; //Hide our registration form.
        }
        //The create user api call was not successful. Present the returned error message from the api.
        else
        {
            FailureText.Text     = createUserResult["Message"];
            ErrorMessage.Visible = true;

            Registration.Visible = false; //Hide our registration form.
        }
    }