ASP.NET标识 - 使用不同的授权字段

时间:2015-03-22 02:32:21

标签: c# asp.net asp.net-identity

我已将我的应用程序连接到ASP.NET Identity环境中使用ASP.NET MVC,并且效果很好。我喜欢它。但我对它所使用的领域存在问题;

具体来说,是login方法。

    //
    // POST: /Account/Login
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    [Route("account/login")]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) {
        if (ModelState.IsValid) {
            var user = await UserService.FindAsync(model.UserName, model.Password);
            if (user != null) {
                await SignInAsync(user, model.RememberMe);
                return RedirectToLocal(returnUrl);
            }
            else {
                ModelState.AddModelError("", "Invalid username or password.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

    private async Task SignInAsync(Member user, bool isPersistent) {
        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

        var identity = await UserService.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

        AuthenticationManager.SignIn(
            new AuthenticationProperties() {
                IsPersistent = isPersistent
            },
            identity);
    }

这将使用针对UserName系统编码的Member类的IUser字段创建身份验证票证。现在,这确实有效,但我希望它使用Email字段。

原因是因为我使用User.Identity.Name来做某些事情,我真的希望它等于Email字段中的值。

不幸的是,Email上没有IUser字段。我很难搞清楚如何做到这一点。现在,我这样做是通过将UserName设置为始终获取或设置电子邮件字段,就像这样。

public class Member : IUser {
   // ...
   public string Email { get; set; }
   public string UserName { get { return Email; } set { Email = value; } }
   // ...
}

但这是一种非常'hacky'的方式,我想学习一种更干净的方法。

1 个答案:

答案 0 :(得分:1)

我认为你需要扩展IIdentity和IPrincipal。我写了一篇帖子here

//We will create a user identity class.This class will implement IIdentity interface.

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


namespace TechBook.Presentation.LoginClasses
{
    public class UserIdentity: IIdentity
    {
        private bool isAuthenticated;
        private string authenticationType;
        private string userID;
        private string firstName;
        private string lastName;
        private List roles;

        public UserIdentity(string UserID, bool IsAuthenticated, string AuthenticationType)
        {
            userID = UserID;
            isAuthenticated = IsAuthenticated;
            authenticationType = AuthenticationType;
        }


        public bool IsAuthenticated
        {
            get { return isAuthenticated; }
        }
        public string AuthenticationType
        {
            get { return authenticationType; }
        }


        public string Name
        {
            get { return userID; }
        }


        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }


        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }


        public List Roles
        {
            get { return roles; }
            set { roles = value; }
        }
    }
}


//We will create a custom principal class. The class will implement IPrincipal interface.   


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


namespace TechBook.Presentation.LoginClasses
{
    public class UserPrincipal :IPrincipal
    {
        private UserIdentity _userIdentity;


        public UserPrincipal(UserIdentity userIdentity)
        {
            _userIdentity = userIdentity;
        }


        public System.Security.Principal.IIdentity Identity
        {
            get { return _userIdentity; }
        }


        public bool IsInRole(string role)
        {
            return _userIdentity.Roles.Contains(role);
        }
    }
}

/*We have created these classes as we know identity and role are must to implement authentication and authorization.  Application must be able to identify the user.

Now we need to write code for user authentication. */

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

namespace TechBook.Presentation.LoginClasses
{
    public class SecurityManager
    {
        public bool Authenticate(string userName, string password)
        {
            BusinessEngine.Users user = new BusinessEngine.Users();

            user.UserName = userName;
            user.Password = password;

            if (new Business.Controller.UserController().validateUser(user) == 1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public UserPrincipal ConstructUserPrincipal(System.Security.Principal.IIdentity iidentity)
        {
            int userId = Convert.ToInt32(iidentity.Name);

            if (userId &gt; 0)
            {
                BusinessEngine.Users user = new BusinessEngine.Users();
                user = new Business.Controller.UserController().getUserById(userId);

                UserIdentity uidentity = new UserIdentity(userId.ToString(), iidentity.IsAuthenticated, iidentity.AuthenticationType);
                uidentity.FirstName = user.FirstName;
                uidentity.LastName = user.LastName;

                List role = new List();
                if (user.UserType.ToString().ToUpper().Equals("A"))
                {
                    role.Add("Admin");
                    uidentity.Roles = role;
                }

                UserPrincipal uprincipal = new UserPrincipal(uidentity);

                return uprincipal;
            }
            else
            {
                return null;
            }
        }
    }
}

/*We have kept the userId in Context.User.Identity.Name (see UserIdentity class). using this we can query the database and get the user information. 

Login Code*/


protected void btnLogin_Click(object sender, EventArgs e)
        {
            TechBook.Presentation.LoginClasses.SecurityManager obj = new                    TechBook.Presentation.LoginClasses.SecurityManager();
            if (obj.Authenticate(txtUserName.Text.Trim(), txtPassword.Text.Trim()))
            {
                BusinessEngine.Users user = new BusinessEngine.Users();
                user.UserName = txtUserName.Text.Trim();
                user.Password = txtPassword.Text.Trim();

                user = new Business.Controller.UserController().getUser(user);
                FormsAuthentication.RedirectFromLoginPage(user.UserId.ToString(), false);
            }
        }

/*We need user and role information everytime a request is received and thus we need to bind the code with authentication module. 

Global.asax code*/


protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            if (this.User != null)
            {
                TechBook.Presentation.LoginClasses.SecurityManager obj = new TechBook.Presentation.LoginClasses.SecurityManager();

                TechBook.Presentation.LoginClasses.UserPrincipal principal = obj.ConstructUserPrincipal(this.User.Identity);

                this.Context.User = principal;

            }
        }