ASP.NET Identity 使用简介

1. 什么是 ASP.NET Identity

ASP.NET Identity 是微软推出,用于在ASP.NET应用中管理用户的组件。

 

The mainstay for user management in recent years has been ASP.NET Membership, which has suffered from design choices. The biggest limitation is that the schema used to store the data worked only with SQL Server and was difficult to extend without re-implementing a lot of provider classes. The schema itself was overly complex, which made it harder to implement changes than it should have been.

  --Pro ASP.NET MVC 5 Platform

 

2. 如何配置ASP.NET Identity with MySQL

2.1 配置ASP.NET Identity

2.1.1 安装相应的组件包

Microsoft.AspNet.Identity.EntityFramework

Microsoft.AspNet.Identity.OWIN

Microsoft.Owin.Host.SystemWeb

 

2.1.2 自定义核心组件

$ User model

默认的user model是 IdentityUser(Microsoft.AspNet.Identity.EntityFramework)。这个类有12个内建的属性,如 Id、UserName、PasswordHash、Email等

一般,根据业务需求,我们需要其它额外的属性。我们可以创建一个继承自IdentityUser的自定义类,在这个自定义类中添加额外的属性。

using Microsoft.AspNet.Identity.EntityFramework

public class AppUser : IdentityUser {
    // 在这里添加额外的属性
}

 

$ DB Context

一般我们需要改变Identity用到的数据库表的名称。默认的数据库表为:AspNetUsers、AspNetUserRoles、AspNetUserLogins、AspNetUserCliams、AspNetRoles。

using System.Data.Entity;
using Microsoft.Asp.Net.Identity.EntityFramework;
public class AppIdentityDbContext : IdentityDbContext<AppUser> {
    public AppIdentityDbContext() : base("IdentityDb") { }
    public AppIdentityDbContext(string connectionString)
        : base(connectionString) {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<AppUser>().ToTable("user");
        modelBuilder.Entity<IdentityRole>().ToTable("role");
        modelBuilder.Entity<IdentityUserRole>().ToTable("userrole");
        modelBuilder.Entity<IdentityUserClaim>().ToTable("userclaim");
        modelBuilder.Entity<IdentituUserLogin>().ToTable("userlogin");
    }
}

 

$ DB 初始化

如果你不熟悉Identity的数据库表的结构,可以通过代码让Identity自动创建。

如果你比较熟悉,那我推荐用专业的数据库管理工具来创建,如MySQL Workbench。

代码示例。一般初始化代码只需要执行一次,好好斟酌策略,防止数据被删。

using System.Data.Entity;
public class AppIdentityDbContext : IdentityDbContext<AppUser> {
    ...
    static AppIdentityDbContext() {
        Database.SetInitializer<AppIdentityDbContext>(new IdentityDbInit());
    }
}

 

using System.Data.Entity;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;

public class IdentityDbInit : DropCreateDatabaseAlways<AppIdentityDbContext> {
    protectedd override void Seed(AppIdentityDbContext context) {
        this.InitAdmin(context);
        base.Seed(context);
    }

    public void InitAdmin(AppIdentityDbContext context) {
        string adminName = "admin";
        string adminPassword = "changeme";
        string adminRoleName = "Administrators";

        // 创建用户
        UserManager<AppUser> userManager = new UserManager<AppUser>(
            new UserStore<AppUser>(context));
        var user = new AppUser { UserName = adminName };
        userManager.Create(user, adminPassword);

        // 创建角色
        RoleManager<IdentityRole> roleManager = new RoleManager<IdentityRole>(
            new RoleStore<IdentityRole>(context));
        var adminRole = roleManager.Create(new IdentityRole(adminRoleName));

        // 给用户赋予角色
        userManager.AddToRole(user.Id, adminRoleName);
    }
}

 

$ 配置

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;

public class IdentityConfig {
    public void Configuration(IAppBuilder app) {
        app.CreatePerOwinContext<AppIdentityDbContext>(() => new AppIdentityDbContext());
        app.CreatePerOwinContext<UserManager<AppUser>>(
            (o, c) => new UserManager<AppUser>(new UserStore<AppUser>(
                c.Get<AppIdentityDbContext>())));
        app.CreatePerOwinContext<RoleManager<IdentityRole>>(
            (o, c) => new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(
                c.Get<AppIdentityDbContext>())));

        app.UseCookieAuthentication(new CookieAuthenticationOptions {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login")
        });
    }
}

 

2.1.3 配置web.config
<configuration>
  <appSettings>
    <add key="owin:AppStartup" value="IdentityConfig" />
    ...
  </appSettings>
  ...
</configuration>

 

2.2 配置MySQL DB

2.2.1 安装相应的组件包

MySql.Data.Entity

 

2.2.2 配置web.config

 

<configuration>
  <configSections>
    <section name="entityFramework"
	         type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework">
  </configSections>
  <system.data>
    <DbProviderFactories>
	  <remove invariant="MySql.Data.MySqlClient" />
	  <add name="MySQL Data Provider"
	       invariant="MySql.Data.MySqlClient"
		   description=".Net Framework Data Provider for MySQL"
		   type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" />
	</DbProviderFactories>
  </system.data>
  <connectionStrings>
    <add name="IdentityDb"
	     connectionString="server=192.168.0.9;user id=tester;password=changeme;database=IdentityDb"
		 providerName="MySql.Data.MySqlClient" />
  </connectionStrings>
  <entityFramework>
    <providers>
	  <provider invariantName="MySql.Data.MySqlClient"
	  type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
	</providers>
  </entityFramework>
</configuration>

 

2.2.3 创建DB

方法一:创建一个没有表的空DB,通过代码让Identity自动创建表。(见上文)

方法二:创建一个带有所有Identity相关表的DB

 

$ User


 

CREATE TABLE `user` (
  `Id` varchar(128) NOT NULL,
  `Email` varchar(256) DEFAULT NULL,
  `EmailConfirmed` tinyint(1) NOT NULL,
  `PasswordHash` longtext,
  `SecurityStamp` longtext,
  `PhoneNumber` longtext,
  `PhoneNumberConfirmed` tinyint(1) NOT NULL,
  `TwoFactorEnabled` tinyint(1) NOT NULL,
  `LockoutEndDateUtc` datetime DEFAULT NULL,
  `LockoutEnabled` tinyint(1) NOT NULL,
  `AccessFailedCount` int(11) NOT NULL,
  `UserName` varchar(256) NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

$ Role


 

CREATE TABLE `role` (
  `Id` varchar(128) NOT NULL,
  `Name` varchar(256) NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

$ UserRole


 

CREATE TABLE `userrole` (
  `UserId` varchar(128) NOT NULL,
  `RoleId` varchar(128) NOT NULL,
  PRIMARY KEY (`UserId`,`RoleId`),
  KEY `IdentityRole_Users` (`RoleId`),
  CONSTRAINT `AppUser_Roles` FOREIGN KEY (`UserId`) REFERENCES `user` (`Id`)
    ON DELETE CASCADE ON UPDATE NO ACTION,
  CONSTRAINT `IdentityRole_Users` FOREIGN KEY (`RoleId`) REFERENCES `role` (`Id`)
    ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

$ UserClaim


 

 

CREATE TABLE `userclaim` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `UserId` varchar(128) NOT NULL,
  `ClaimType` longtext,
  `ClaimValue` longtext,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `Id` (`Id`),
  KEY `UserId` (`UserId`),
  CONSTRAINT `AppUser_Claims` FOREIGN KEY (`UserId`) REFERENCES `user` (`Id`)
    ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

$ UserLogin



 

CREATE TABLE `userlogin` (
  `LoginProvider` varchar(128) NOT NULL,
  `ProviderKey` varchar(128) NOT NULL,
  `UserId` varchar(128) NOT NULL,
  PRIMARY KEY (`LoginProvider`,`ProviderKey`,`UserId`),
  KEY `AppUser_Logins` (`UserId`),
  CONSTRAINT `AppUser_Logins` FOREIGN KEY (`UserId`) REFERENCES `user` (`Id`)
    ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8

 


 

3. 如何使用ASP.NET Identity

3.1 认证(Authenticate)

using System.Security.Claims;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;

public class AccountController : Controller {
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(string name, string password, string returnUrl) {
        var userManager = HttpContext.GetOwinContext()
            .GetUserManager<UserManager<AppUser>>();
        var authManager = HttpContext.GetOwinContext().Authentication;
        var user = userManager.Find(name, password);
        if (user == null) {
            // Invalid name or password
        }
        else {
            ClaimsIdentity identity = userManager.CreateIdentity(
                user, DefaultAuthenticationTypes.ApplicationCookie);
            authManager.SignOut();
            authManager.SignIn(identity);
            return Redirect(returnUrl);
        }

        return View();
    }
}

 

3.2 用户操作

using System.Security.Principal;
using System.Web;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;

var userManager = HttpContext.Current.GetOwinContext()
    .GetUserManager<UserManager<AppUser>>();

// 获取当前用户
IPrincipal principal = HttpContext.Current.User;
AppUser user = userManager.FindByName(principal.Identity.Name);

// 创建用户
var newUser = new AppUser { UserName = "Alice" };
varr password = "changeme";
userManager.Create(newUser, password);

// 删除用户
userManager.Delete(user);

// 修改用户信息
user.Email = "huangc126@126.com";
user.PasswordHash = userManager.PasswordHasher.HashPassword("secret");

 

3.3 角色管理

using System.Web;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;

var roleManager = HttpContext.Current.GetOwinContext()
    .GetUserManager<RoleManager<IdentityRole>>();

// 创建角色
var newRole = new IdentityRole { Name = "Admin" };
roleManager.Create(newRole);

// 将角色授予用户
userManager.AddToRole(userId, role: "Admin");

// 移除用户的角色
userManager.RemoveFromRole(userId, role: "Admin");

// 删除角色
var role = roleManager.FindByName("Admin");
roleManager.Delete(role);

 

3.4 授权(Authorization)

3.4.1 基于角色的授权
using System.Web.Mv;

[Authorize(Roles = "Administrators")]
public class AdminController : Controller {
    ...
}

 

3.4.2 基于声明(Claim)的授权
using System.Security.Claims;
using System.Web;
using System.Web.Mvc;

[ClaimsAccess(Issuer = "RemoteClaims", ClaimType = ClaimTypes.PostalCode, Value = "123456")]
public ActionResult Action() {
    ...
}

public class ClaimsAccessAttribute : AuthorizeAttribute {
    public string Issuer { get; set; }
	public string ClaimType { get; set; }
	public string Value { get; set; }
	
	protected override bool AuthorizeCore(HttpContextBase context) {
	    return context.User.Identity.IsAuthenticated
		    && context.User.Identity is ClaimsIdentity
			&& ((ClaimnsIdentity)context.User.Identity).HasClaim(
			    c => c.Issuer == this.Issuer
				    && c.Type == this.ClaimType
					&& c.Value == this.Value);
	}
}

 

 

4. 小结

ASP.NET Identity非常灵活,支持各种扩展,对中小型系统来说足够用了。虽然看上去有点麻烦,但即使是小系统,我也建议用Identity。因为自己去搞一套太麻烦,又容易出错。我们应该把更多的精力花在业务实现上,而不是去抠底层技术细节。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET Identity是一种用于身份验证和授权的框架,可以轻松地将用户身份验证和授权集成到ASP.NET Web应用程序中。下面是使用ASP.NET Identity进行身份验证和授权的步骤: 1. 导入ASP.NET IdentityASP.NET Web应用程序中,可以通过NuGet包管理器安装ASP.NET Identity。打开NuGet包管理器控制台,输入以下命令: ``` Install-Package Microsoft.AspNet.Identity.Core ``` 这将安装ASP.NET Identity核心库。 2. 创建用户模型 可以创建自定义的用户模型,也可以使用默认的用户模型。如果要创建自定义的用户模型,需要继承IdentityUser类。例如: ```csharp public class ApplicationUser : IdentityUser { public string FullName { get; set; } } ``` 3. 配置身份验证和授权 在Web.config文件中,需要添加以下配置信息: ```xml <authentication mode="None" /> <identity impersonate="false" /> <roleManager enabled="true" /> ``` 这些配置信息将启用基于表的身份验证和授权。 4. 实现用户注册和登录 使用ASP.NET Identity,可以轻松地实现用户注册和登录。例如,可以使用AccountController中的以下方法: ```csharp public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false); return RedirectToAction("Index", "Home"); } AddErrors(result); } return View(model); } public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: default: ModelState.AddModelError("", "Invalid login attempt."); return View(model); } } return View(model); } ``` 5. 实现授权 可以使用ASP.NET Identity实现基于角色的授权。例如,可以使用Authorize属性限制只有特定角色的用户才能访问某些页面: ```csharp [Authorize(Roles = "Admin")] public ActionResult AdminDashboard() { // Only users in the "Admin" role can access this page return View(); } ``` 以上是使用ASP.NET Identity进行身份验证和授权的基本步骤,如果你有更多的问题或疑问,可以告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值