ASP.NET Identity 2集成到MVC5項目--筆記01


Identiry2是微軟推出的Identity的升級版本,較之上一個版本更加易於擴展,總之更好用。如果需要具體細節。網上具體參考Identity2源代碼下載 參考文章 在項目中,是不太想直接把這一堆堆的東西直接放到我們項目中的,我的做法是單獨建立一個解決方案,方便以后懶得寫代碼,類似的可以使用解決方案稍微改改代碼就完事。以下的代碼均是參考或者直接復制Identity2給的簡單示例而來,所以有需要的童鞋可以使用Nuget下載一個演示版本,自己參考代碼達到自己的要求。Identity Samples


ASP.NET Identity 2集成到MVC5項目--筆記01
ASP.NET Identity 2集成到MVC5項目--筆記02


1.目標

  • 擴展用戶字段
  • 擴展角色字段
  • 使用用戶名、郵箱登陸
  • 注冊后郵件注冊登陸
  • ···

2.基礎結構搭建

2.1網站結構搭建

(1)建立一個名為Identity2Study的MVC5項目,身份驗證選擇空
(2) 新建一個解決方案並且命名為Mvc.Identity
(3)在解決方案下建立兩個文件夾分別命名為DAL 和BLL

(4)Nuget下載相關組件
首先下載Identity EntityFramework 2.1.0 下載這個之后Nuget會根據依賴自動幫我們下載Identity Core

PM> Install-Package Microsoft.AspNet.Identity.Core -Version 2.1.0-alpha1 -Pre

還需要下載 Identity Owin 2.1.0

PM> Install-Package Microsoft.AspNet.Identity.Owin -Version 2.1.0-alpha1 -Pre

下載Optimization

Install-Package Microsoft.AspNet.Web.Optimization

下載 Microsoft.Owin.Host.SystemWeb

PM> Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0

這里用命令行下載的時候需要注意:默認項目需要的是Mvc.Identity,如圖:

2.2 擴展用戶屬性

在DAL文件夾中添加如下類(繼承至IdentityUser),例如我們用戶里面需要擴展一個字段用於存儲用戶的頭像URL地址。

public class ApplicationUser : IdentityUser
{
    //在這個類擴展自定義字段
    /// <summary>
    /// 頭像URL
    /// </summary>
    public string headImage { get; set; }

    //添加一個方法 后面會用到
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}

2.3 擴展角色屬性

在DAL文件夾中添加如下類ApplicationRole(繼承至IdentityRole),我們添加一個字段用於描述當前角色的含義。

  public class ApplicationRole : IdentityRole
  {
      public ApplicationRole() : base() { }
      public ApplicationRole(string name) : base(name) { }

      /// <summary>
      /// 角色描述
      /// </summary>
      [DisplayName("角色描述")]
      public string Description { get; set; }
  }

2.4 數據持久化(數據庫上下文)

我們使用的Identity是基於EF框架的CodeFirst來完成數據持久保存的。所以需要添加數據庫上下文。在DAL文件夾添加如下類ApplicationDbContext(繼承至IdentityDbContext )

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    static ApplicationDbContext()
    {
        //Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

}

2.5 用戶管理業務邏輯實現

在BLL文件夾下添加如下類ApplicationUserManager(繼承至UserManager )封裝了一些方法比如創建用戶

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options,
        IOwinContext context)
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };
        // Configure user lockout defaults
        manager.UserLockoutEnabledByDefault = true;
        manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
        manager.MaxFailedAccessAttemptsBeforeLockout = 5;
        // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
        // You can write your own provider and plug in here.
        manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser>
        {
            MessageFormat = "Your security code is: {0}"
        });
        manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
        {
            Subject = "SecurityCode",
            BodyFormat = "Your security code is {0}"
        });
        //manager.EmailService = new EmailService();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider =
                new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}

2.6 角色管理業務邏輯實現

在BLL文件夾下添加如下類ApplicationRoleManager(繼承至RoleManager

public class ApplicationRoleManager : RoleManager<ApplicationRole>
{
    public ApplicationRoleManager(IRoleStore<ApplicationRole, string> roleStore)
        : base(roleStore)
    {
    }

    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
    {
        return new ApplicationRoleManager(new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>()));
    }
}

2.7 登錄業務邏輯實現

在BLL文件夾下添加如下類ApplicationSignInManager(繼承至SignInManager<ApplicationUser, string>)

public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) :
        base(userManager, authenticationManager) { }

    public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
    {
        return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
    }

    public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
    {
        return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
    }
}

2.8 郵件發送業務邏輯實現

用於發送郵件,在BLL文件夾下面建立類EmailService(繼承至IIdentityMessageService)

    public class EmailService : IIdentityMessageService
    {
        public Task SendAsync(IdentityMessage message)
        {
            var credentialUserName = "郵箱登錄名";
            var sentFrom = "你的郵箱地址";
            var pwd = "郵箱登錄密碼";

            System.Net.Mail.SmtpClient client =
                new System.Net.Mail.SmtpClient("smtp服務器地址");

            client.Port = 25;//smtp郵件服務器端口
            client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
            client.UseDefaultCredentials = false;

            System.Net.NetworkCredential credentials =
                new System.Net.NetworkCredential(credentialUserName, pwd);

            client.EnableSsl = true;
            client.Credentials = credentials;

            var mail =
                new System.Net.Mail.MailMessage(sentFrom, message.Destination);

            mail.Subject = message.Subject;
            mail.Body = message.Body;
            return client.SendMailAsync(mail);
        }
    }

這個類添加完畢后需要我們在ApplicationUserManager類下面的create方法里面大概55行左右添加如下代碼用於我們在新建用戶的時候會收到一封確認注冊的郵件

manager.EmailService = new EmailService();

2.9 添加默認賬號和角色

在DAL文件夾下面的ApplicationDbContext.cs添加一個數據初始化策略類名為ApplicationDbInitializer(繼承至DropCreateDatabaseIfModelChanges

public class ApplicationDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext>
{
    protected override void Seed(ApplicationDbContext context)
    {
        InitializeIdentityForEF(context);
        base.Seed(context);
    }

    //Create User=Admin@Admin.com with password=Admin@123456 in the Admin role        
    public static void InitializeIdentityForEF(ApplicationDbContext db)
    {
        var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
        const string name = "Admin@Admin.com";
        const string password = "Admin@Admin123";
        const string roleName = "Admin";

        //Create Role Admin if it does not exist
        var role = roleManager.FindByName(roleName);
        if (role == null)
        {
            role = new ApplicationRole(roleName);
            var roleresult = roleManager.Create(role);
        }

        var user = userManager.FindByName(name);
        if (user == null)
        {
            user = new ApplicationUser { UserName = name, Email = name };
            var result = userManager.Create(user, password);
            result = userManager.SetLockoutEnabled(user.Id, false);
        }

        // Add user admin to Role Admin if not already added
        var rolesForUser = userManager.GetRoles(user.Id);
        if (!rolesForUser.Contains(role.Name))
        {
            var result = userManager.AddToRole(user.Id, role.Name);
        }
    }
}

建立完畢后記得把ApplicationDbContext類里面構造函數的初始化策略取消注釋

Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());

如果允許到這里提示httpcontext未定義,則需要我們添加System.Web組件。自行在引用搜一下加到解決方案即可。

到這里,項目的大致結構搭建完成
這篇只是搭建一個大致的框架,下一篇才是想要的功能。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM