如何为 .NET Core Web API 进行安全身份验证?
Posted
技术标签:
【中文标题】如何为 .NET Core Web API 进行安全身份验证?【英文标题】:How to make secure authentication for .NET Core Web API? 【发布时间】:2020-11-15 14:47:57 【问题描述】:我正在使用 .NET Core Web API、Entity Framework 和 React 开发一个应用程序。我最近一直在阅读很多关于我的 API 可能的身份验证技术的文章,我发现普通 JWT 并不完全安全,所以起初我决定将 OpenID Connect 与 IdentityServer 4 一起使用。我了解 OAuth 2.0 和 OpenID 背后的想法Connect 是在登录过程中隐藏用户凭据,并让外部身份验证提供商参与发布访问令牌,但我不想依赖此类服务,因为并非每个人都在 Facebook 等上拥有帐户。我认为这是一种可选方式登录。我想让用户只需登录名和密码即可登录。那么在现代网络应用中实现这一目标的最佳(安全)方式是什么?
将项目 1 作为客户端应用程序,将项目 2 作为 API 资源,将项目 3 作为授权服务 (IdentityServer4),我考虑以下场景:
用户可以在授权服务上创建一个帐户,该帐户负责颁发通过客户端应用程序访问 API 资源所需的令牌。授权服务仅注册为我的客户端应用程序的授权提供者。
使用资源所有者密码授权从授权服务获取授权令牌 - 规范不推荐使用此令牌,但在我的情况下,因为用户必须向授权服务提供凭据,并且我将托管每个项目,我看不到任何问题.
不用担心 OAuth 并使用 ASP.NET Core Identity + Bearer token 身份验证来实现授权机制。
高度赞赏的任何想法或建议。
【问题讨论】:
也许我的回答here 有用。 【参考方案1】:我使用 JwtBearer 包,将其连接到您的 Startup.cs 配置方法中,例如
.UseJwtBearerAuthentication(new JwtBearerOptions
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = new TokenValidationParameters
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["AppSettings:AuthConfig:SecretKey"])),
ValidateIssuer = true,
ValidIssuer = Configuration["AppSettings:AuthConfig:Issuer"],
ValidateAudience = true,
ValidAudience = Configuration["AppSettings:AuthConfig:Audience"],
ValidateLifetime = true,
)
我的用户控制器上的登录操作看起来像
[HttpPost]
public string Post([FromBody]LoginRequest request)
var contact = dbContext.Contacts.Where(c => c.Active && c.Email == request.Email).Select(c => new c.Id, c.PasswordHash ).SingleOrDefault();
if (contact == null || !Security.PasswordHash.ValidatePassword(request.Password, contact.PasswordHash))
return string.Empty;
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(appSettings.AuthConfig.SecretKey));
var now = DateTime.UtcNow;
var claims = new Claim[]
new Claim(JwtRegisteredClaimNames.Sub, contact.Id.ToString()),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.Now.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
;
var jwt = new JwtSecurityToken(
issuer: appSettings.AuthConfig.Issuer,
audience: appSettings.AuthConfig.Audience,
claims: claims,
notBefore: now,
expires: now.AddDays(30),
signingCredentials: new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256));
jwt.Payload.Add("roles", dbContext.ContactRoles.Where(cr => cr.ContactId == contact.Id).Select(ur => ur.Role.Name).ToArray());
return new JwtSecurityTokenHandler().WriteToken(jwt);
我在客户端为 Angular 使用 JWT 包,React 可能有类似的东西。
【讨论】:
以上是关于如何为 .NET Core Web API 进行安全身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 dotnet core(web Api) 代码更改以及 TypeScript 代码更改启用实时重新加载
.使用 Mongodb 进行 Net Core Web Api 身份验证
如何为 .NET Core 3.0 中 WPF 配置依赖注入 ?