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

10

I'm trying to create a login control for my application but I'm not finding a way to do this. I would like it to be a full login control, where I could register new users, retrieve their passwords, etc.

Can anyone give me a hint how to do this?

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

    
asked by anonymous 17.06.2014 / 05:59

1 answer

8

I'll give you an example of the login infrastructure I have here. Basically it's a Controller , plus the base access providers based on Membership . It is a somewhat old but well didactic approach.

First of all, install the following NuGet packages into your solution:

  

link    link    link

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 implementation help, just talk.

    
17.06.2014 / 07:54