Asp.Net Core WebApi身份验证、注册、用户管理

  • 用户服务
  • 用户实体、用户模型及数据上下文
  • 应用程序设置文件
  • 在Startup.cs中配置身份验证
  • 参考文献

用了两天的时间研究了在Asp.Net WebApi 项目中如何实现注册、登录、身份验证功能。此项目使用JWT(Json Web Token)来进行身份验证。

用户服务

ASP.NET Core用户服务负责与用户身份验证,注册和管理相关的所有数据库交互和核心业务逻辑。

该文件的顶部包含一个定义用户服务的接口,下面是实现该接口的具体用户服务类。该类的底部包含一些私有方法,用于创建和验证存储在数据库中的散列密码。

  1. 通过Emain和Password来登录服务,Authenticate方法调用VerifyPasswordHash来验证Email和密码是否正确来进行登录授权。
public User Authenticate(string email, string password){if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password))return null;var user = _iUserRepository.GetUserByEmail(email);// check if username existsif (user == null)return null;// check if password is correctif (!VerifyPasswordHash(password, user.PasswordHash, user.PasswordSalt))return null;// authentication successfulreturn user;}

private static bool VerifyPasswordHash(string password, byte[] storedHash, byte[] storedSalt){if (password == null) throw new ArgumentNullException(nameof(password));if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "password");if (storedHash.Length != 64) throw new ArgumentException("Invalid length of password hash (64 bytes expected).", "passwordHash");if (storedSalt.Length != 128) throw new ArgumentException("Invalid length of password salt (128 bytes expected).", "passwordHash");using (var hmac = new System.Security.Cryptography.HMACSHA512(storedSalt)){var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));for (int i = 0; i < computedHash.Length; i++){if (computedHash[i] != storedHash[i]) return false;}}return true;}
  1. 用户注册时需要创建新用户并将用户数据存放到数据库中
public User Create(User user, string password){// validationif (string.IsNullOrWhiteSpace(password))throw new AppException("Password is required");if (_iUserRepository.Any(x => x.Email == user.Email))throw new AppException("Email \"" + user.Email + "\" is already taken");if (_iUserRepository.Any(x => x.UserName == user.UserName))throw new AppException("Username \"" + user.UserName + "\" is already taken");CreatePasswordHash(password, out var passwordHash, out var passwordSalt);user.PasswordHash = passwordHash;user.PasswordSalt = passwordSalt;_iUserRepository.Add(user);return user;}

对密码进行加密存储

private static void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt){if (password == null) throw new ArgumentNullException(nameof(password));if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "password");using (var hmac = new System.Security.Cryptography.HMACSHA512()){passwordSalt = hmac.Key;passwordHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));}}
  1. 用户信息更新及删除代码
public void Update(User userParam, string password = null){var user = _iUserRepository.GetById(userParam.Id);if (user == null)throw new AppException("User not found");if (userParam.UserName != user.UserName){// username has changed so check if the new username is already takenif (_iUserRepository.Any(x => x.UserName == userParam.UserName))throw new AppException("Username " + userParam.UserName + " is already taken");}// update user propertiesuser.FirstName = userParam.FirstName;user.LastName = userParam.LastName;user.UserName = userParam.UserName;// update password if it was enteredif (!string.IsNullOrWhiteSpace(password)){CreatePasswordHash(password, out var passwordHash, out var passwordSalt);user.PasswordHash = passwordHash;user.PasswordSalt = passwordSalt;}_iUserRepository.Update(user);}public void Delete(string id){var user = _iUserRepository.GetById(id);if (user != null){_iUserRepository.Remove(user);}}

用户实体、用户模型及数据上下文

public class User{public string Id { get; set; }public string FirstName { get; set; }public string LastName { get; set; }public string UserName { get; set; }public string Email { get; set; }public byte[] PasswordHash { get; set; }public byte[] PasswordSalt { get; set; }}
public class UserModel{public string Id { get; set; }public string FirstName { get; set; }public string LastName { get; set; }public string UserName { get; set; }public string Email { get; set; }public string Password { get; set; }}
public class VueContext : DbContext{public VueContext(DbContextOptions<VueContext> options): base(options){}public DbSet<User> User { get; set; }}

应用程序设置文件

/appsettings.json

{"AppSettings": {"Secret": "THIS IS USED TO SIGN AND VERIFY JWT TOKENS, REPLACE IT WITH YOUR OWN SECRET, IT CAN BE ANY STRING"},"Logging": {"IncludeScopes": false,"LogLevel": {"Default": "Warning"}},"AllowedHosts": "*","ConnectionStrings": {"VueDatabase": "serverName;Database=VueDb;Trusted_Connection=True;"}
}

在Startup.cs中配置身份验证

添加以下代码到ConfigureServices方法中以添加身份验证服务

// configure strongly typed settings objectsvar appSettingsSection = Configuration.GetSection("AppSettings");services.Configure<AppSettings>(appSettingsSection);// configure jwt authenticationvar appSettings = appSettingsSection.Get<AppSettings>();var key = Encoding.ASCII.GetBytes(appSettings.Secret);services.AddAuthentication(x =>{x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(x =>{x.Events = new JwtBearerEvents{OnTokenValidated = context =>{var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();var userId = context.Principal.Identity.Name;var user = userService.GetById(userId);if (user == null){// return unauthorized if user no longer existscontext.Fail("Unauthorized");}return Task.CompletedTask;}};x.RequireHttpsMetadata = false;x.SaveToken = true;x.TokenValidationParameters = new TokenValidationParameters{ValidateIssuerSigningKey = true,IssuerSigningKey = new SymmetricSecurityKey(key),ValidateIssuer = false,ValidateAudience = false};});

对应用配置身份验证,添加以下代码到Configure中

app.UseAuthentication();

核心代码大概就这些。最近看了微软官方文档,但是并没有发现详细教程,最终发现一篇博客,提取核心内容搬运记录下来。

参考文献

http://jasonwatmore.com/post/2018/06/26/aspnet-core-21-simple-api-for-authentication-registration-and-user-management#user-service-cs

https://neilq.github.io/2018/07/14/secure-your-asp-net-core-2-1-api-1-issuing-a-JWT/

https://www.cnblogs.com/RainingNight/p/jwtbearer-authentication-in-asp-net-core.html

Asp.Net Core WebApi 身份验证、注册、用户管理相关推荐

  1. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分

    目录 介绍 JWT(JSON Web令牌) ASP.NET Core中的JWToken配置 用户模型类 创建令牌 第1步 第2步 第4步 令牌存储 中间件 自定义中间件app.Use() 中间件app ...

  2. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第2部分

    目录 介绍 用户角色 如何创建自定义授权特性? AuthorizeAttribute AuthorizeFilter 如何在控制器和操作方法级别设置权限? 检查用户权限的扩展方法 如何在操作方法(内联 ...

  3. ASP.NET Core的身份认证框架IdentityServer4(3)-术语的解释

    ASP.NET Core的身份认证框架IdentityServer4(3)-术语的解释 原文:ASP.NET Core的身份认证框架IdentityServer4(3)-术语的解释 IdentityS ...

  4. ASP.NET Core的身份认证框架IdentityServer4--入门【转】

    原文地址 Identity Server 4是IdentityServer的最新版本,它是流行的OpenID Connect和OAuth Framework for .NET,为ASP.NET Cor ...

  5. 将经过身份验证的用户注入Spring MVC @Controllers

    可以使用@AuthenticationPrincipal批注和AuthenticationPrincipalArgumentResolver这是Spring MVS MethodArgumentRes ...

  6. ASP.NET Core WebApi构建API接口服务实战演练

    一.ASP.NET Core WebApi课程介绍 人生苦短,我用.NET Core!提到Api接口,一般会想到以前用到的WebService和WCF服务,这三个技术都是用来创建服务接口,只不过Web ...

  7. ASP.Net Core WebApi几种版本控制对比

    ASP.Net Core WebApi几种版本控制对比 原文:ASP.Net Core WebApi几种版本控制对比 一.版本控制的好处: (1)有助于及时推出功能, 而不会破坏现有系统. (2)它还 ...

  8. NET问答: 如何将 ASP.NET Core WebAPI 中抛出的异常封装成对象?

    咨询区 rianjs: 在 ASP.NET Core WebAPI 中,我的 Controller 代码如下: [Route("create-license/{licenseKey}&quo ...

  9. 【源码解读】Vue与ASP.NET Core WebAPI的集成

    在前面博文[Vue]Vue 与 ASP.NET Core WebAPI 的集成中,介绍了集成原理:在中间件管道中注册SPA终端中间件,整个注册过程中,终端中间件会调用node,执行npm start命 ...

最新文章

  1. php1为true,php有一个预定义的常量true,值为整数1,这该如何理解?
  2. openstack介绍(二)
  3. php执行zip压缩,PHP执行zip与rar解压缩方法实现代码
  4. c+++11并发编程语言,C++11并发编程:多线程std:thread
  5. jQuery通过event获取点击事件的事件对象
  6. 万里航行总舵手——业务测试架构的设计
  7. 上位机和下位机有什么区别和关系?常用上位机软件开发工具介绍
  8. 表格序号_Word办公技巧:如何为文档中的表格添加居中对齐的自动序号?
  9. DAVIS2016+Matlab+Win10使用指南
  10. Wallpaper Engine壁纸提取
  11. 6.10力扣 10号出去逛街了,11号补上! 打印n位数
  12. CDH 6系列(CDH 6.0.0、CDH 6.1.0、CDH 6.2.0等)安装和使用
  13. Java HashMap中在resize()时候的rehash,即再哈希法的理解
  14. java 容器排序_Java攻略第四章 容器类、排序
  15. 命名需谨慎!科技产品荒谬命名大盘点
  16. 支付宝开通海外退税 阿里腾讯暗战跨境O2O_21世纪网
  17. 服务器ip多有什么作用是什么,使用多ip服务器有什么优势呢?
  18. 知道创宇区块链安全实验室|Meter.io 攻击事件分析
  19. 无线振动传感器在工厂环境中的应用
  20. 2020年磺化工艺考试题库及磺化工艺考试APP

热门文章

  1. NTFS分区结构及图片文档结构
  2. Linux下BMP图片截图
  3. WPF--控件(代码讲解)
  4. 合成大西瓜游戏|微信合成大西瓜游戏技巧及资源
  5. wish - 简单的窗口式(windowing) shell
  6. Linux集群的安装和配置
  7. 有趣现象:同一个java文件中有2个类,一个public,一个无类修饰符,各有一个main函数,谁在前先执行谁!
  8. php 7.3 新特性
  9. crontab 奇数时间定时执行
  10. MD5 加密安全吗?