6

I need to set my login to use username instead of email address, how can I change it? I've looked everywhere but they are MVC codes not web forms.

I appreciate your efforts in reaching a solution for my problem.

using System;
using System.Web;
using System.Web.UI;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Owin;
using Web_WebApp.Models;

namespace Web_WebApp.Account
{
    public partial class Login : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            RegisterHyperLink.NavigateUrl = "Register";
            // Enable this once you have account confirmation enabled for password reset functionality
            //ForgotPasswordHyperLink.NavigateUrl = "Forgot";
            OpenAuthLogin.ReturnUrl = Request.QueryString["ReturnUrl"];
            var returnUrl = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
            if (!String.IsNullOrEmpty(returnUrl))
            {
                RegisterHyperLink.NavigateUrl += "?ReturnUrl=" + returnUrl;
            }
        }

        protected void LogIn(object sender, EventArgs e)
        {
            if (IsValid)
            {
                // Validate the user password
                var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
                var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();

                // This doen't count login failures towards account lockout
                // To enable password failures to trigger lockout, change to shouldLockout: true
                var result = signinManager.PasswordSignIn(UserName.Text, Password.Text, RememberMe.Checked, shouldLockout: false);

                switch (result)
                {
                    case SignInStatus.Success:
                        IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
                        break;
                    case SignInStatus.LockedOut:
                        Response.Redirect("/Account/Lockout");
                        break;
                    case SignInStatus.RequiresVerification:
                        Response.Redirect(String.Format("/Account/TwoFactorAuthenticationSignIn?ReturnUrl={0}&RememberMe={1}", 
                                                        Request.QueryString["ReturnUrl"],
                                                        RememberMe.Checked),
                                          true);
                        break;
                    case SignInStatus.Failure:
                    default:
                        FailureText.Text = "Invalid login attempt";
                        ErrorMessage.Visible = true;
                        break;
                }
            }
        }
    }
}

using System;
using System.Linq;
using System.Web;
using System.Web.UI;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Owin;
using Web_WebApp.Models;


namespace Web_WebApp.Account
{
    public partial class Register : Page
    {
        protected void CreateUser_Click(object sender, EventArgs e)
        {

            var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
            var signInManager = Context.GetOwinContext().Get<ApplicationSignInManager>();
            var user = new ApplicationUser() { UserName = UserName.Text, Email = Email.Text, FirstName = FirstName.Text, MiddleName = MiddleName.Text, LastName = LastName.Text };
            IdentityResult result = manager.Create(user, Password.Text);
            if (result.Succeeded)
            {
                // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
                //string code = manager.GenerateEmailConfirmationToken(user.Id);
                //string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
                //manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.");

                signInManager.SignIn( user, isPersistent: false, rememberBrowser: false);
                IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
            }
            else 
            {
                ErrorMessage.Text = result.Errors.FirstOrDefault();
            }
        }
    }
}
Kevin Maxwell
  • 907
  • 2
  • 19
  • 38
  • Are the username/email pairs contained in a database? If so, you could write yourself a method for checking the username/password pair if you have a match. – Gnqz Jul 27 '15 at 07:53
  • Thanks @Gnqz, No, they are not. For example: username: KevinM email:Kevin.Maxwell@app.com – Kevin Maxwell Jul 27 '15 at 07:55
  • There is a dependency between the username and email? Is there a common format? – Gnqz Jul 27 '15 at 07:56
  • In my identity user table, I have two fields 1)email 2)username which by default when you register username is actually derived from email. I've changed that so during registration I get two fields to enter 1)email 2)username. But by default login asks for email. I don't know where should I change this. It seems MVC programmers are happier since it's lot easier to change it. – Kevin Maxwell Jul 27 '15 at 07:59
  • Then you could just write a function which looks up the email from the user name. It will take a string(username) and return string(email)? – Gnqz Jul 27 '15 at 08:02
  • How can I do this and where? – Kevin Maxwell Jul 27 '15 at 08:03
  • You mentioned identity user table. Is it SQL, MySQL, Access? – Gnqz Jul 27 '15 at 08:06
  • it's Microsoft SQL database – Kevin Maxwell Jul 27 '15 at 08:06
  • Can you communicate with the database or you haven't yet write down the methods to do so? – Gnqz Jul 27 '15 at 08:08
  • I still haven't done that. I thought there would be way to point to username instead of email. – Kevin Maxwell Jul 27 '15 at 08:18
  • Probably a duplicate of: http://stackoverflow.com/questions/27501533/use-username-instead-of-email-for-identity-in-asp-net-mvc5 – Nikolay Jul 27 '15 at 08:22
  • @Nikolay The link you have posted is for MVC, I am not a web developer, but I'm not sure MVC and WebForms are so similar. – Gnqz Jul 27 '15 at 08:25
  • @Nikolay, it's MVC :( – Kevin Maxwell Jul 27 '15 at 08:35

2 Answers2

2

If you look at the SignInManagerExtensions.PasswordSignIn MSDN, this will tell you that the first argument in the PasswordSignIn method is userName.

MVC & WebForms by default set this to Email as you register with an email address. You can change the Register Action too to allow registering with a UserName, this by default adds the email as UserName and Email in the database.

protected void CreateUser_Click(object sender, EventArgs e)
{
    // ...
    // UserName and Email are both set to Email.text
    // Add a UserName TextBox and Replace UserName = Email.Text with UserName = UserName.Text
    var user = new ApplicationUser() { UserName = Email.Text, Email = Email.Text };
    // ...
}


protected void LogIn(object sender, EventArgs e)
{
    if (IsValid)
    {
        // ...
        // The first argument is userName
        // Replace mail.Text with UserName.Text
        var result = signinManager.PasswordSignIn(mail.Text, Password.Text, RememberMe.Checked, shouldLockout: false);
        // ..
    }
}

Replace:

<div class="form-group">
    <asp:Label runat="server" AssociatedControlID="Email" CssClass="col-md-2 control-label">Email</asp:Label>
    <div class="col-md-10">
        <asp:TextBox runat="server" ID="Email" CssClass="form-control" TextMode="Email" />
        <asp:RequiredFieldValidator runat="server" ControlToValidate="Email"
            CssClass="text-danger" ErrorMessage="The email field is required." />
    </div>
</div>

With:

<div class="form-group">
    <asp:Label runat="server" AssociatedControlID="UserName" CssClass="col-md-2 control-label">UserName</asp:Label>
    <div class="col-md-10">
        <asp:TextBox runat="server" ID="UserName" CssClass="form-control" />
        <asp:RequiredFieldValidator runat="server" ControlToValidate="UserName"
            CssClass="text-danger" ErrorMessage="The username field is required." />
    </div>
</div>

I Hope this makes sense.

shammelburg
  • 6,974
  • 7
  • 26
  • 34
2

You could simply find the user by username or anything you want and then sign in the user with SignIn method directly:

protected void LogIn(object sender, EventArgs e)
{
    if (IsValid)
    {
        // Validate the user password
        var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();

        // assuming you have a text box named UserName
        var user=manager.FindByName(UserName.Text);
        // or for advanced scenarios you can write:
        // var user = manager.Users.FirstOrDefault(u => u.UserName == UserName.Text);
        if(user !=null)
        {
            if(manager.CheckPassword(user, Password.Text))
            {
                signinManager.SignIn(user, false, RememberMe.Checked);
                IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
            }
        }
    }
    FailureText.Text = "Invalid login attempt";
    ErrorMessage.Visible = true;
}
Sam FarajpourGhamari
  • 14,601
  • 4
  • 52
  • 56
  • Thank you Sam for your answer but it seems I can't get this to work. Maybe I'm doing something wrong in here. I'm updating my codes above. – Kevin Maxwell Jul 27 '15 at 11:42
  • Could you submit your register user method too? – Sam FarajpourGhamari Jul 27 '15 at 11:45
  • When you are using my code what happening? Error? or what? – Sam FarajpourGhamari Jul 27 '15 at 11:58
  • I tried to place your codes between my codes and nothing happened and then I commented my codes and used yours only and again nothing happened. By nothing I mean it was giving the invalid attempt error. I'm sure I did something wrong, can you please combine your code with mine and then provide it here? – Kevin Maxwell Jul 27 '15 at 12:02
  • I have updated the code. But please register a new user and test it with the new user – Sam FarajpourGhamari Jul 27 '15 at 12:14
  • your solution worked actually. The other solution from Sander worked as well. Is there any way I can flag both of you as completed? – Kevin Maxwell Jul 27 '15 at 12:19
  • As I understood, during registration the first argument var user = new ApplicationUser() { UserName = UserName.Text, Email = Email.Text, FirstName = FirstName.Text, MiddleName = MiddleName.Text, LastName = LastName.Text } , which is UserName takes the main order for login session. Correct? – Kevin Maxwell Jul 27 '15 at 12:22
  • No. think about which solution is more general and could help other readers more for similar situation then flag it. – Sam FarajpourGhamari Jul 27 '15 at 12:22
  • By default asp.net save email as user name. but you could change it as you did. On the other hand in sign in `Identity` uses user itself to generate `claims` not username or email. Therefore if you find the user by username or email or whatever you want you simply could sign in – Sam FarajpourGhamari Jul 27 '15 at 12:30
  • Thank you very much @Sam for your help and support. – Kevin Maxwell Jul 27 '15 at 12:31
  • I have another question but I believe I should open a new ticket for it. It's about site.master where it says Hello Username. I want to change it to show the First Name which I have added into Identity user table.
  • Hello, <%: Context.User.Identity.GetUserName() %> !
  • – Kevin Maxwell Jul 27 '15 at 12:35
  • Yes open another question. I will answer it. – Sam FarajpourGhamari Jul 27 '15 at 12:38
  • Here it is: http://stackoverflow.com/questions/31653451/how-to-change-the-greeting-message-on-asp-net-from-username-to-first-name-or-any – Kevin Maxwell Jul 27 '15 at 12:44