编写自定义的验证类ASP.NET 5

编程入门 行业动态 更新时间:2024-10-11 21:25:27
本文介绍了编写自定义的验证类ASP.NET 5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

的开箱即用ASP.NET 5身份类是直线前进,这是易于安装和使用,但我的问题是,我与我有自定义现有的用户和权限表的遗留系统工作为识别系统。该识别系统似乎很可插拔的,但我不能找到如何编写自定义身份类的任何适当的文件。是否有

任何文件
  • 如何编写自定义的,可容纳遗留系统的用户和权限表ASP.NET 5标识类
  • 如何设置使用自定义标识类用在ASP.NET 5,6 MVC应用程序?
  • 解决方案

    有没有大量的文档资料可用,所以我用最新的身份类这是目前发挥各地 Microsoft.AspNet.Identity .EntityFramework 3.0.0-RC1决赛,并想出了正与我的遗产用户数据库表的解决方案。

    首先确保您的旧用户实体类实现 IdentityUser 类,使我们可以ASP.NET 5

    中使用的类认证

    公共类MyLegacyUser:IdentityUser{    //你MyLegacyUser属性将去这里像往常一样}

    请确保您忽略,你会不喜欢使用 IdentityUser 类继承的任何属性(这些都是不包含用户表中的属性)。我们通过使用中的流畅API实现的 OnModelCreating 的的DbContext 类的方法。

    公共类MyDbContext:的DbContext{    公共DbSet< MyLegacyUser> MyLegacyUser {搞定;组; }    //为简单起见,我将在这里只添加OnModelCreating方法    保护覆盖无效OnModelCreating    {        modelBuilder.Entity< MyLegacyUser>(实体=>        {            entity.Ignore(E => e.AccessFailedCount);            entity.Ignore(E => e.Claims);            entity.Ignore(E => e.ConcurrencyStamp);            entity.Ignore(E => e.Email);            entity.Ignore(E => e.EmailConfirmed);            entity.Ignore(E => e.Id);            entity.Ignore(E => e.LockoutEnabled);            entity.Ignore(E => e.LockoutEnd);            entity.Ignore(E => e.Logins);            entity.Ignore(E => e.NormalizedEmail);            entity.Ignore(E => e.NormalizedUserName);            entity.Ignore(E => e.PasswordHash);            entity.Ignore(E => e.PhoneNumber);            entity.Ignore(E => e.PhoneNumberConfirmed);            entity.Ignore(E => e.Roles);            entity.Ignore(E => e.SecurityStamp);            entity.Ignore(E => e.TwoFactorEnabled);        }    }}

    现在我们必须实现自己的自定义的UserManager 类与我们的传统用户进行身份验证。确保你的新类实施的UserManager< T> ,其中 T 是 MyLegacyUser 。一旦做到这一点重写 CheckPasswordAsync 你的用户进行身份验证。

    注意:的 CheckPasswordAsync 方法并不负责返回一个身份验证的用户,它只是将返回true或false指示的方法如果用户被成功认证。通过身份验证的用户被其他类设置,我下面会解释。

    公共类MyLegacyUserManager:&的UserManager LT; MyLegacyUser>{    公共WorldUserManager(IUserStore< MasterUser>商店,IOptions< IdentityOptions> optionsAccessor,IPasswordHasher< MasterUser> passwordHasher,IEnumerable的< IUserValidator< MasterUser>> userValidators,IEnumerable的< IPasswordValidator< MasterUser>> passwordValidators,ILookupNormalizer keyNormalizer,IdentityErrorDescriber错误,IServiceProvider的服务, ILogger<&的UserManager LT; MasterUser>>记录仪,IHttpContextAccessor ​​contextAccessor):基地(商店,optionsAccessor,passwordHasher,userValidators,passwordValidators,keyNormalizer,错误,服务,记录仪,contextAccessor)    {    }    公共覆盖异步任务<布尔> CheckPasswordAsync(MasterUser用户,字符串密码)    {        //这是处理用户身份验证自己的身份验证管理器类       //添加您自己的code在这里验证您的用户        返回新的AuthenticationManager()进行身份验证(user.EmailAddress,密码)。    }}

    一旦做到这一点,我们必须实现我们自己的 UserStore 类。还有可以实现几个接口,如 IUserStore< T> , IUserLoginStore< T> , IUserClaimsStore< T> 等我实现了 IUserClaimsStore< T> 接口和实施 GetUserIdAsync , GetUserNameAsync , FindByIdAsync 和 GetClaimsAsync 方法

    公共类MyLegacyUserClaimStore:IUserClaimStore< MyLegacyUser>{    //我在这里简单地回到我收到的用户输入参数的用户名    公共任务<串GT; GetUserIdAsync(MasterUser用户的CancellationToken的CancellationToken)    {        返回Task.Run(()=> user.UserName,的CancellationToken);    }}//我在这里简单地回到我收到的用户输入参数的用户名公共任务<串GT; GetUserNameAsync(MasterUser用户的CancellationToken的CancellationToken){    返回Task.Run(()=> user.UserName,的CancellationToken);}公共任务< MasterUser> FindByIdAsync(字符串userid,的CancellationToken的CancellationToken){    //这是我的经理类读取我的用户的用户id    //添加您自己的code读到这里为集ID用户    返回Task.Run(()=>新建MyLegacyUserUserManager()ReadForEmailAddress(用户ID,0,真实,真)的CancellationToken);} 公共任务< MasterUser> FindByNameAsync(字符串normalizedUserName,的CancellationToken的CancellationToken) {     //这是我的经理类读取我的用户为normalizedUserName    //添加您自己的code读到这里的一套normalizedUserName用户     返回Task.Run(()=>新建MyLegacyUserManager()ReadForEmailAddress(normalizedUserName,0,真实,真)的CancellationToken); }//如果你想利用索赔确保你在这里将它们映射//如果你不使用要求,需要考虑其他的IUserStore接口之一//如IUserLoginStore,这样你就不必执行GetClaimsAsync方法公共异步任务<&IList的LT;权利要求GT;> GetClaimsAsync(MasterUser用户的CancellationToken的CancellationToken){    VAR索赔=新的List<权利要求GT;();    的foreach(VAR索赔user.Claims)    {        claims.Add(新索赔(claim.ClaimType,claim.ClaimValue));    }    返回索赔;}

    这些都是你需要进行自定义验证的类。没有让我们配置我们在 Startup.cs自定义的验证方法类。添加以下到 ConfigureServices 法

    公共无效ConfigureServices(IServiceCollection服务){     //使用默认的角色,IdentityRole因为我们没有实现角色     //添加我们的自定义的UserManager和UserStore类     services.AddIdentity< MyLegacyUser,IdentityRole&GT(配置=>        {            config.User.RequireUniqueEmail = TRUE;            config.Cookies.ApplicationCookie.AccessDeniedPath =新Microsoft.AspNet.Http.PathString(/认证/登录);            config.Cookies.ApplicationCookie.LoginPath =新Microsoft.AspNet.Http.PathString(/认证/登录);            config.Cookies.ApplicationCookie.LogoutPath =新Microsoft.AspNet.Http.PathString(/认证/登录);        })        .AddUserManager< MyLegacyUserManager>()        .AddUserStore< MyLegacyUserUserClaimStore>()        .AddEntityFrameworkStores< MyDbContext>();}

    在配置方法确保您指定要使用的功能,身份验证

    注意:您使用的语句的顺序很重要,请确保您包括 UseIdentity 在 UseMvc 如果你正在使用MVC。

    公共异步无效配置(IApplicationBuilder应用程序){    app.UseIdentity();    //你useMvc等使用的语句会去这里}

    现在我们已经配置了自定义验证类,我们可以使用默认的 SignInManager 类认证。下面是一个例子我 AuthController 类

    公共类AuthController:控制器{    私人SignInManager< MyLegacyUserUser> _signInManager;    公共AuthController(SignInManager< MasterUser> signInManager)    {        _signInManager = signInManager;    }    //为简单起见,我将只在这里添加登录动作    [HttpPost]    公共异步任务< IActionResult>登录(LoginViewModel loginViewModel)    {        VAR的结果=等待_signInManager.PasswordSignInAsync(loginViewModel.Username,loginViewModel.Password,真,假);        如果(结果== SignInResult.Success)        {            返回RedirectToAction(指数,SomeControllerToRedirectTo);        }        等待_signInManager.SignOutAsync();        返回RedirectToAction(登录,验证);    }}

    当你的用户进行身份验证就可以访问该用户的权利要求你会使用MVC 5完成的,例如:

    VAR电子邮件= User.Claims.FirstOrDefault(C => c.Type.Equals(ClaimTypes.Email))值。

    The out of the box ASP.NET 5 Identity classes are straight forward and it is easy to setup and use, my problem however is that I'm working with a legacy system with existing user and permission tables that I have to customize the Identity system for. The Identity system seems very pluggable, but I can't find any proper documentation on how to write custom Identity classes. Is there any documentation on

  • How to write custom ASP.NET 5 Identity classes that can cater for legacy system user and permission tables
  • How do I setup the use of the custom Identity classes for use in a ASP.NET 5, MVC 6 application?
  • 解决方案

    There is not a lot of documentation available yet, so I played around with the latest Identity classes which is currently Microsoft.AspNet.Identity.EntityFramework 3.0.0-rc1-final and came up with a solution that is working with my legacy user database tables.

    First of all make sure that your legacy user entity class implement the IdentityUser class so that we can use the class for authentication within ASP.NET 5

    public class MyLegacyUser : IdentityUser { // Your MyLegacyUser properties will go here as usual }

    Make sure that you ignore any properties inherited from the IdentityUser class that you would not like to use (Those are the properties not contained within your user table). We do this by using the fluent api within the OnModelCreating method of the DbContext class.

    public class MyDbContext : DbContext { public DbSet<MyLegacyUser> MyLegacyUser { get; set; } // For simplicity I will add only the OnModelCreating method here protected override void OnModelCreating { modelBuilder.Entity<MyLegacyUser>(entity => { entity.Ignore(e => e.AccessFailedCount); entity.Ignore(e => e.Claims); entity.Ignore(e => e.ConcurrencyStamp); entity.Ignore(e => e.Email); entity.Ignore(e => e.EmailConfirmed); entity.Ignore(e => e.Id); entity.Ignore(e => e.LockoutEnabled); entity.Ignore(e => e.LockoutEnd); entity.Ignore(e => e.Logins); entity.Ignore(e => e.NormalizedEmail); entity.Ignore(e => e.NormalizedUserName); entity.Ignore(e => e.PasswordHash); entity.Ignore(e => e.PhoneNumber); entity.Ignore(e => e.PhoneNumberConfirmed); entity.Ignore(e => e.Roles); entity.Ignore(e => e.SecurityStamp); entity.Ignore(e => e.TwoFactorEnabled); } } }

    Now we have to implement our own custom UserManager class to authenticate with our legacy user. Make sure that your new class implement UserManager<T>, where T is your MyLegacyUser. Once this is done override the CheckPasswordAsync to authenticate your user.

    Note: The CheckPasswordAsync method is not responsible for returning an authenticated user, it is simply a method that will return true or false to indicate if the user was successfully authenticated. The authenticated user is set by another class which I will explain below.

    public class MyLegacyUserManager : UserManager<MyLegacyUser> { public WorldUserManager(IUserStore<MasterUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<MasterUser> passwordHasher, IEnumerable<IUserValidator<MasterUser>> userValidators, IEnumerable<IPasswordValidator<MasterUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<MasterUser>> logger, IHttpContextAccessor contextAccessor) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger, contextAccessor) { } public override async Task<bool> CheckPasswordAsync(MasterUser user, string password) { // This is my own authentication manager class that handles user authentication // Add your own code to authenticate your user here return new AuthenticationManager().Authenticate(user.EmailAddress, password); } }

    Once this is done we have to implement our own UserStore class. There are a few interfaces you can implement such as IUserStore<T>, IUserLoginStore<T>, IUserClaimsStore<T> etc. I implemented the IUserClaimsStore<T> interface and implemented the GetUserIdAsync, GetUserNameAsync, FindByIdAsync and GetClaimsAsync methods

    public class MyLegacyUserClaimStore : IUserClaimStore<MyLegacyUser> { // Here I simply returned the username of the user parameter I recieved as input public Task<string> GetUserIdAsync(MasterUser user, CancellationToken cancellationToken) { return Task.Run(() => user.UserName, cancellationToken); } } // Here I simply returned the username of the user parameter I recieved as input public Task<string> GetUserNameAsync(MasterUser user, CancellationToken cancellationToken) { return Task.Run(() => user.UserName, cancellationToken); } public Task<MasterUser> FindByIdAsync(string userId, CancellationToken cancellationToken) { // This is my manager class to read my user for the userId // Add your own code to read the user for the set Id here return Task.Run(() => new MyLegacyUserUserManager().ReadForEmailAddress(userId, 0, true, true), cancellationToken); } public Task<MasterUser> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken) { // This is my manager class to read my user for the normalizedUserName // Add your own code to read the user for the set normalizedUserName here return Task.Run(() => new MyLegacyUserManager().ReadForEmailAddress(normalizedUserName, 0, true, true), cancellationToken); } // If you want to make use of Claims make sure that you map them here // If you do not use claims, consider implementing one of the other IUserStore interfaces //such as the IUserLoginStore so that you do not have to implement the GetClaimsAsync method public async Task<IList<Claim>> GetClaimsAsync(MasterUser user, CancellationToken cancellationToken) { var claims = new List<Claim>(); foreach (var claim in user.Claims) { claims.Add(new Claim(claim.ClaimType, claim.ClaimValue)); } return claims; }

    These are all the classes you need for custom authentication. No let's configure our custom authentication method in the Startup.cs class. Add the following to the ConfigureServices method

    public void ConfigureServices(IServiceCollection services) { // Use the default role, IdentityRole as we are not implementing roles // Add our custom UserManager and UserStore classes services.AddIdentity<MyLegacyUser, IdentityRole>(config => { config.User.RequireUniqueEmail = true; config.Cookies.ApplicationCookie.AccessDeniedPath = new Microsoft.AspNet.Http.PathString("/Auth/Login"); config.Cookies.ApplicationCookie.LoginPath = new Microsoft.AspNet.Http.PathString("/Auth/Login"); config.Cookies.ApplicationCookie.LogoutPath = new Microsoft.AspNet.Http.PathString("/Auth/Login"); }) .AddUserManager<MyLegacyUserManager>() .AddUserStore<MyLegacyUserUserClaimStore>() .AddEntityFrameworkStores<MyDbContext>(); }

    In the Configure method make sure that you specify that you want to use the Identity functionality to authenticate

    Note: The order of your use statements are important, make sure that you include UseIdentity before UseMvc if you are using Mvc.

    public async void Configure(IApplicationBuilder app) { app.UseIdentity(); // Your useMvc and other use statements will go here }

    Now we have configured our custom authentication classes and we can authenticate by using the default SignInManager class. Here is an example of my AuthController class

    public class AuthController : Controller { private SignInManager<MyLegacyUserUser> _signInManager; public AuthController(SignInManager<MasterUser> signInManager) { _signInManager = signInManager; } // For simplicity I will only add the Login action here [HttpPost] public async Task<IActionResult> Login(LoginViewModel loginViewModel) { var result = await _signInManager.PasswordSignInAsync(loginViewModel.Username, loginViewModel.Password, true, false); if (result == SignInResult.Success) { return RedirectToAction("Index", "SomeControllerToRedirectTo"); } await _signInManager.SignOutAsync(); return RedirectToAction("Login", "Auth"); } }

    When your user is authenticated you can access the user claims as you would have done with MVC 5, for example

    var email = User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Email)).Value;

    更多推荐

    编写自定义的验证类ASP.NET 5

    本文发布于:2023-11-14 04:00:55,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1586159.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:自定义   ASP   NET

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!