How to create a login and password page in ASP.NET?

Asked

Viewed 2,783 times

10

I’m trying to create a login control for my application but I’m not finding a way to do that. I would like it to be a complete login control, where I can register new users, recover their passwords, etc.

Can someone give me a tip on how to do this?

I know Visual Studio has the tools but I never touched it and I would like to learn.

  • What platform are you developing?

1 answer

8

I’ll give you an example of the login infrastructure I have here. It’s basically a Controller, plus basic access providers based on Membership. It’s an old approach, but very didactic.

First of all, install in your solution the following Nuget packages:

https://www.nuget.org/packages/Microsoft.AspNet.WebPages.WebData/3.1.2 https://www.nuget.org/packages/Microsoft.AspNet.WebPages.Data/3.1.2 https://www.nuget.org/packages/Microsoft.AspNet.WebPages/3.1.2

Controllers/Logincontroller.Cs

namespace MeuProjeto.Controllers
{
    public class LoginController : Controller
    {
        private MeuProjetoContext _db = new MeuProjetoContext();
        //
        // GET: /Login/

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Index(UserLogin userLogin)
        {
            if (ModelState.IsValid && WebSecurity.Login(userLogin.Username, userLogin.Password, persistCookie: true))
            {
                return RedirectToAction("Index", "Home", new { area = "" });
            }

            // Se chegou aqui, re-exibir form. Modelo inválido.
            ModelState.AddModelError("", "Usuário ou senha incorretos.");
            return View(userLogin);
        }

        public ActionResult RecuperarSenha()
        {
            ViewBag.ErrorMessage = "";
            return View();
        }

        [HttpPost]
        public ActionResult RecuperarSenha(string email)
        {
            string errorMsg = string.Empty;

            if (!string.IsNullOrEmpty(email))
            {
                List<Usuario> users = _db.Usuarios.Where(usr => usr.Email == email).ToList();

                if (users.Count == 0)
                {
                    errorMsg = "E-Mail não encontrado";
                }
                else
                {
                    Usuario user = users[0];

                    string url = string.Format("{0}/{1}/{2}", Request.Url.GetLeftPart(UriPartial.Authority), "Login/ResetPassword", user.UsuarioId);

                    string bodyMail = "Olá " + user.Nome + @"\r\n";
                    bodyMail += "Para redefinir a sua senha clique <a href=\"" + url + "\">aqui</a><br>";

                    EmailMessage msg = new EmailMessage();
                    msg.To = user.Email;
                    msg.Subject = "Redefinir senha";
                    msg.Body = bodyMail;
                    msg.Send();
                    errorMsg = "E-Mail enviado com sucesso";
                }
            }
            else
            {
                errorMsg = "E-Mail não pode estar em branco";
            }

            ViewBag.ErrorMessage = errorMsg;
            return View();
        }

        public ActionResult Logout()
        {
            WebSecurity.Logout();
            return RedirectToAction("Index", "Login", new { area = "" });
        }

        protected override void Dispose(bool disposing)
        {
            _db.Dispose();
            base.Dispose(disposing);
        }
    }
}

Web.Config

  <system.web>
    <roleManager enabled="true" defaultProvider="CustomRoleProvider">
      <providers>
        <clear />
        <add name="CustomRoleProvider" type="MeuProjeto.Site.Infrastructure.CustomRoleProvider" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </roleManager>
    <membership defaultProvider="CustomMembershipProvider">
      <providers>
        <clear />
        <add name="CustomMembershipProvider" type="MeuProjeto.Site.Infrastructure.CustomMembershipProvider" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>
    <sessionState mode="InProc" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>
    <customErrors mode="Off" />
  </system.web>

Infrastructure/Custommembershipprovider.Cs

using MeuProjeto.Core.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Web;
using System.Web.Configuration;
using System.Web.Security;
using WebMatrix.WebData;

namespace MeuProjeto.Infrastructure
{
    public class CustomMembershipProvider : ExtendedMembershipProvider
    {
        #region Class Variables

        private int newPasswordLength = 8;
        private string connectionString;
        private string applicationName;
        private bool enablePasswordReset;
        private bool enablePasswordRetrieval;
        private bool requiresQuestionAndAnswer;
        private bool requiresUniqueEmail;
        private int maxInvalidPasswordAttempts;
        private int passwordAttemptWindow;
        private MembershipPasswordFormat passwordFormat;
        private int minRequiredNonAlphanumericCharacters;
        private int minRequiredPasswordLength;
        private string passwordStrengthRegularExpression;
        private MachineKeySection machineKey; //Used when determining encryption key values.

        #endregion

        static public byte[] RandomSalt
        {
            get
            {
                byte[] salt = new byte[48];
                using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
                    rngCsp.GetBytes(salt);
                return salt;
            }
        }

        private byte[] GeneratePasswordHash(byte[] salt, string password)
        {
            Byte[] bytes;
            using (SHA256 hasher = SHA256.Create())
            {
                System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
                bytes = encoding.GetBytes(password);

                hasher.TransformBlock(salt, 0, salt.Length, salt, 0);
                hasher.TransformFinalBlock(bytes, 0, bytes.Length);

                bytes = hasher.Hash;
            }

            return bytes;
        }

        private String GeneratePassword(string newpassword)
        {
            byte[] salt = RandomSalt;
            byte[] passHash = GeneratePasswordHash(salt, newpassword);

            // concatenates the salt and hash in one vector
            byte[] finalData = new byte[salt.Length + passHash.Length];
            Array.Copy(salt, finalData, salt.Length);
            Array.Copy(passHash, 0, finalData, salt.Length, passHash.Length);

            return System.Convert.ToBase64String(finalData);
        }

        private bool ByteArraysEqual(byte[] b1, byte[] b2)
        {
            if (b1 == b2) return true;
            if (b1 == null || b2 == null) return false;
            if (b1.Length != b2.Length) return false;
            for (int i = 0; i < b1.Length; i++)
            {
                if (b1[i] != b2[i]) return false;
            }
            return true;
        } 

        public override bool ConfirmAccount(string accountConfirmationToken)
        {
            throw new NotImplementedException();
        }

        public override bool ConfirmAccount(string userName, string accountConfirmationToken)
        {
            throw new NotImplementedException();
        }

        public override string CreateAccount(string userName, string password, bool requireConfirmationToken)
        {
            throw new NotImplementedException();
        }

        public override string CreateUserAndAccount(string userName, string password, bool requireConfirmation, IDictionary<string, object> values)
        {
            ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(userName, password, true);

            OnValidatingPassword(args);

            if (args.Cancel)
            {
                // return MembershipCreateStatus.InvalidPassword;
                throw new MembershipCreateUserException(MembershipCreateStatus.InvalidPassword);
            }

            var CustomMembershipUser = GetUser(userName);

            if (CustomMembershipUser == null)
            {
                // try
                // {
                using (var context = new MeuProjetoContext())
                {
                    var hashedPassword = GeneratePassword(password);

                    var user = new Usuario { 
                        UsuarioId = Guid.NewGuid(),
                        Email = userName,
                        Nome = values["Name"].ToString(),
                        Senha = hashedPassword,
                        Ativo = true
                    };

                    context.Usuarios.Add(user);
                    context.SaveChanges();

                    var membership = new MeuProjeto.Core.Models.Membership();

                    membership.MembershipId = Guid.NewGuid();
                    membership.Usuario = user;
                    membership.Password = hashedPassword;
                    context.Memberships.Add(membership);
                    context.SaveChanges();

                    return MembershipCreateStatus.Success.ToString();
                }
            }
            else
            {
                // return MembershipCreateStatus.DuplicateUserName;
                throw new MembershipCreateUserException(MembershipCreateStatus.DuplicateUserName);
            }
        }

        public override MembershipUser GetUser(string username, bool userIsOnline = true)
        {
            CustomMembershipUser CustomMembershipUser = null;
            using (var context = new MeuProjetoContext())
            {
                try
                {
                    var user = context.Usuarios.Where(u => u.Email == username).SingleOrDefault();

                    if (user != null)
                    {
                        CustomMembershipUser = new CustomMembershipUser(
                            this.Name,
                            user.Email,
                            user.UsuarioId,
                            user.Email,
                            "",
                            "",
                            true,
                            false,
                            user.CreatedOn,
                            DateTime.Now,
                            DateTime.Now,
                            default(DateTime),
                            default(DateTime),
                            user.Email);
                    }
                }
                catch { }
            }

            return CustomMembershipUser;
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override string GetUserNameByEmail(string email)
        {
            throw new NotImplementedException();
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredPasswordLength
        {
            get { throw new NotImplementedException(); }
        }

        public override int PasswordAttemptWindow
        {
            get { throw new NotImplementedException(); }
        }

        public override System.Web.Security.MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotImplementedException(); }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresUniqueEmail
        {
            get { throw new NotImplementedException(); }
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(System.Web.Security.MembershipUser user)
        {
            throw new NotImplementedException();
        }

        public override bool ValidateUser(string username, string password)
        {
            using (var context = new MeuProjetoContext())
            {
                if (context == null) throw new InvalidOperationException();

                var user = (from u in context.Usuarios
                            where u.Email == username && u.Ativo == true
                            select u).FirstOrDefault();

                if (user != null)
                {
                    byte[] pwdHash = GeneratePasswordHash(user.Salt, password);
                    if (ByteArraysEqual(pwdHash, user.Hash))
                    {
                        bool isAdm = true;

                        System.Web.Security.FormsAuthenticationTicket ticket = new System.Web.Security.FormsAuthenticationTicket(1,
                          user.UsuarioId.ToString() + "#" + username,
                          DateTime.Now,
                          DateTime.Now.AddMinutes(15),
                          false,
                          isAdm ? "#" + user.Nome : user.Nome,
                          System.Web.Security.FormsAuthentication.FormsCookiePath);

                        #if DEBUG
                        System.Diagnostics.Debugger.Log(0, "SEC", "User " + username + " logged in at " + ticket.IssueDate.ToString());
                        #endif

                        // Encrypt the ticket.
                        string encTicket = System.Web.Security.FormsAuthentication.Encrypt(ticket);

                        HttpContext.Current.Response.Cookies.Add(new HttpCookie(System.Web.Security.FormsAuthentication.FormsCookieName, encTicket));
                        return true;
                    }
                }

                return false;
            }
        }
    }
}

Infrastructure/Custommembershipuser.Cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace MeuProjeto.Infrastructure
{
    public class CustomMembershipUser : MembershipUser
    {
        public string Name { get; set; }

        public CustomMembershipUser(
            string providername,
            string username,
            object providerUserKey,
            string email,
            string passwordQuestion,
            string comment,
            bool isApproved,
            bool isLockedOut,
            DateTime creationDate,
            DateTime lastLoginDate,
            DateTime lastActivityDate,
            DateTime lastPasswordChangedDate,
            DateTime lastLockedOutDate,
            // int companyFK,
            string name) :

            base(providername,
                username,
                providerUserKey,
                email,
                passwordQuestion,
                comment,
                isApproved,
                isLockedOut,
                creationDate,
                lastLoginDate,
                lastPasswordChangedDate,
                lastActivityDate,
                lastLockedOutDate)
        {
            // CompanyFK = companyFK;
            Name = name;
        }
    }
}

Infrastructure/Customroleprovider.Cs

using MeuProjeto.Core.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;

namespace MeuProjeto.Infrastructure
{
    public class CustomRoleProvider : RoleProvider
    {
        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            try
            {
                using (var context = new MeuProjetoContext())
                {
                    foreach (string username in usernames)
                    {
                        // find each user in users table
                        var user = context.Usuarios.Where(u => u.Email == username).FirstOrDefault();

                        if (user != null)
                        {
                            // find all roles that are contained in the roleNames
                            var AllDbRoles = context.Roles.ToList();

                            List<Role> UserRoles = new List<Role>();

                            foreach (var roleName in roleNames)
                            {
                                var role = context.Roles.SingleOrDefault(r => r.Name == roleName);

                                if (role == default(Role))
                                {
                                    throw new Exception("Role does not exist.");
                                }

                                UserRoles.Add(role);
                            }


                            if (UserRoles.Count > 0)
                            {
                                foreach (var role in UserRoles)
                                {
                                    if (!context.UserRoles.Where(ur => ur.UsuarioId == user.UsuarioId && ur.RoleId == role.RoleId).Any())
                                    {
                                        var userRole = new UserRole();
                                        userRole.UserRoleId = Guid.NewGuid();
                                        userRole.Usuario = user;
                                        userRole.Role = role;
                                        context.UserRoles.Add(userRole);
                                        context.SaveChanges();
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public override void CreateRole(string roleName)
        {
            try
            {
                if (!RoleExists(roleName))
                {
                    using (var context = new MeuProjetoContext())
                    {
                        Role role = new Role();
                        role.RoleId = Guid.NewGuid();
                        role.Name = roleName;
                        context.Roles.Add(role);
                        context.SaveChanges();
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            using (var context = new MeuProjetoContext())
            {
                try
                {
                    Role role = context.Roles.Where(r => r.Name == roleName).SingleOrDefault();

                    if (role != null)
                    {
                        context.Roles.Remove(role);
                        context.SaveChanges();
                        return true;
                    }
                }
                catch
                {
                    return false;
                }
            }

            return false;
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            List<string> users = new List<string>();

            using (var context = new MeuProjetoContext())
            {
                try
                {
                    var usersInRole = context.UserRoles.Where(ur => ur.Role.Name == roleName && ur.Usuario.Email == usernameToMatch).ToList();

                    if (usersInRole != null)
                    {
                        foreach (var userInRole in usersInRole)
                        {
                            users.Add(userInRole.Usuario.Email);
                        }
                    }
                }
                catch { }
            }

            return users.ToArray();
        }

        public override string[] GetAllRoles()
        {
            List<string> roles = new List<string>();

            using (var context = new MeuProjetoContext())
            {
                try
                {
                    var dbRoles = context.Roles.ToList();

                    foreach (var role in dbRoles)
                    {
                        roles.Add(role.Name);
                    }
                }
                catch { }
            }

            return roles.ToArray();
        }

        public override string[] GetRolesForUser(string username)
        {
            List<string> roles = new List<string>();

            using (var context = new MeuProjetoContext())
            {
                try
                {
                    var dbRoles = context.UserRoles.Where(r => r.Usuario.Email == username).ToList();

                    foreach (var role in dbRoles)
                    {
                        roles.Add(role.Role.Name);
                    }
                }
                catch { }
            }

            return roles.ToArray();
        }

        public override string[] GetUsersInRole(string roleName)
        {
            List<string> users = new List<string>();

            using (var context = new MeuProjetoContext())
            {
                try
                {
                    var usersInRole = context.UserRoles.Where(ur => ur.Role.Name == roleName).ToList();

                    if (usersInRole != null)
                    {
                        foreach (var userInRole in usersInRole)
                        {
                            users.Add(userInRole.Usuario.Email);
                        }
                    }
                }
                catch { }
            }

            return users.ToArray();
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            using (var context = new MeuProjetoContext())
            {
                try
                {
                    var usersInRole = context.UserRoles.SingleOrDefault(ur => ur.Usuario.Email == username && ur.Role.Name == roleName);

                    if (usersInRole != default(UserRole))
                    {
                        return true;
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

            return false;
        }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            try
            {
                using (var context = new MeuProjetoContext())
                {
                    foreach (string username in usernames)
                    {
                        // find each user in users table
                        var user = context.Usuarios.Where(u => u.Email == username).SingleOrDefault();

                        if (user != null)
                        {
                            // find all roles that are contained in the roleNames
                            var AllDbRoles = context.Roles.ToList();

                            List<Role> RemoveRoles = new List<Role>();

                            foreach (var role in AllDbRoles)
                            {
                                foreach (string roleName in roleNames)
                                {
                                    if (role.Name == roleName)
                                    {
                                        RemoveRoles.Add(role);
                                        continue;
                                    }
                                }
                            }

                            if (RemoveRoles.Count > 0)
                            {
                                foreach (var role in RemoveRoles)
                                {
                                    UserRole userRole = context.UserRoles
                                                            .Where(ur => ur.UsuarioId == user.UsuarioId && ur.RoleId == role.RoleId)
                                                            .SingleOrDefault();

                                    if (userRole != null)
                                    {
                                        context.UserRoles.Remove(userRole);
                                        context.SaveChanges();
                                    }
                                }
                            }
                        }
                    }
                }
            }

            catch { }
        }

        public override bool RoleExists(string roleName)
        {
            using (var context = new MeuProjetoContext())
            {
                // check if role exits
                return context.Roles.Any(r => r.Name == roleName);              
            }
        }
    }
}

If you need help with implementation, just say the word.

  • can help me implement?

  • @Joaopaulo First implement all classes. Then modify the methods CreateUserAndAccount and ValidateUser of CustomMembershipProvider with the particularities of your system. If more questions arise, ask other questions with the question and the specific code snippet that I will answer whenever possible.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.