.NET Core 2.0 身份和 jwt?
Posted
技术标签:
【中文标题】.NET Core 2.0 身份和 jwt?【英文标题】:.NET Core 2.0 Identity AND jwt? 【发布时间】:2018-12-21 08:30:31 【问题描述】:我一直在四处寻找并尝试对 .NET Core Identity (https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.1&tabs=visual-studio%2Caspnetcore2x) 和 Jwt(json Web 令牌)进行更多研究。我一直在我的 .NET Core 2.0 应用中使用默认身份作为身份验证/授权,到目前为止它运行良好。
我遇到了障碍,我认为这是我理解 .NET Core 身份和 jwt 的方式。我的应用程序有 MVC 和 web api。我理想地希望保护 web api,但我听说现在最好的方法是通过 jwt。好 - 酷。
我可以继续配置 jwt,然后将其用作我的身份验证/授权 (https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/),但是 - 我是否需要继续并启动一个新服务器作为 jwt 的授权服务器?如果是这样,我不会那样做(太贵了)。
如果我确实使用 jwt,我的 .NET Core 身份代码会怎样?那是不是必须要走了?如果它可以共存,我如何使用 Identity 授权我的 MVC 页面并使用 jwt 授权我的 api 端点?
我知道这是一个开放式问题,但它的核心是:
.NET Core Identity 和 JWT 可以共存吗?还是我必须选择其中之一?我有 MVC 和 web api,并希望保护两者。
【问题讨论】:
你调查过这个吗? medium.com/@ozgurgul/… 您可以简单地使用SignInManager
验证用户的登录,使用UserManager
获取声明,最后使用它创建一个JWT。
Two AuthorizationSchemes in ASP.NET Core 2 很好地涵盖了这一点。
【参考方案1】:
您可以验证用户名和密码并生成 Jwt。
首先,确保您的 API 在 startup.cs 中设置了以下默认身份:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
其次,您可以使用以下方式验证登录:
您可以像这样设置 API 控制器:
[ApiController, Route("check")]
public class TokenController : ControllerBase
private readonly SignInManager<IdentityUser> signin;
public TokenController(SignInManager<IdentityUser> signin)
this.signin = signin;
[HttpGet]
public async Task<string> Get(string user, string pass)
var result = await signin.PasswordSignInAsync(user, pass, true, false);
if (result.Succeeded)
string token = "";
return token;
return null;
在您的 get 函数中,您现在可以生成您的 Jwt。
【讨论】:
【参考方案2】:是的,你可以。 逻辑过程在这个方法中:
第 1 步:获取用户声明
var identity = await GetClaimsIdentity(credentials.UserName, credentials.Password);
您将进入 GetClaimsIdentity
private async Task<ClaimsIdentity> GetClaimsIdentity(string userName, string password)
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
return await Task.FromResult<ClaimsIdentity>(null);
var userToVerify = await _userManager.FindByNameAsync(userName);
if (userToVerify == null)
userToVerify = await _userManager.FindByEmailAsync(userName);
if (userToVerify == null)
return await Task.FromResult<ClaimsIdentity>(null);
// check the credentials
if (await _userManager.CheckPasswordAsync(userToVerify, password))
_claims = await _userManager.GetClaimsAsync(userToVerify);
return await Task.FromResult(_jwtFactory.GenerateClaimsIdentity(userToVerify.UserName, userToVerify.Id, _claims));
// Credentials are invalid, or account doesn't exist
return await Task.FromResult<ClaimsIdentity>(null);
第 2 步:将您需要添加到令牌的所有用户声明分组 - 使用 System.Security.Claims
public ClaimsIdentity GenerateClaimsIdentity(string userName, string id, IList<Claim> claims)
claims.Add(new Claim(Helpers.Constants.Strings.JwtClaimIdentifiers.Id, id));
// If your security is role based you can get then with the RoleManager and add then here as claims
// Ask here for all claims your app need to validate later
return new ClaimsIdentity(new GenericIdentity(userName, "Token"), claims);
第 3 步:然后返回您的方法,您必须生成并返回 JWT 令牌
jwt = await jwtFactory.GenerateEncodedToken(userName, identity);
return new OkObjectResult(jwt);
要生成令牌,请执行以下操作:
public async Task<string> GenerateEncodedToken(string userName, ClaimsIdentity identity)
List<Claim> claims = new List<Claim>();
//Config claims
claims.Add(new Claim(JwtRegisteredClaimNames.Sub, userName));
claims.Add(new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()));
claims.Add(new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(), ClaimValueTypes.Integer64));
//End Config claims
claims.AddRange(identity.FindAll(Helpers.Constants.Strings.JwtClaimIdentifiers.Roles));
claims.AddRange(identity.FindAll("EspecificClaimName"));
// Create the JWT security token and encode it.
var jwt = new JwtSecurityToken(
issuer: _jwtOptions.Issuer,
audience: _jwtOptions.Audience,
claims: claims,
notBefore: _jwtOptions.NotBefore,
expires: _jwtOptions.Expiration,
signingCredentials: _jwtOptions.SigningCredentials);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
return encodedJwt;
有很多方法可以做到这一点。 最常见的是: 验证身份用户 --> 获取用户标识符 --> 根据标识符生成并返回令牌 --> 对端点使用授权
希望有帮助
【讨论】:
以上是关于.NET Core 2.0 身份和 jwt?的主要内容,如果未能解决你的问题,请参考以下文章
.NET Core 2.0 和 EF 下是不是需要使用 IdentityDbContext 进行 JWT 身份验证?
同一站点中的 asp net core 2.0 JWT 和 Openid Connect 身份验证
asp.net core 2.0 授权在身份验证(JWT)之前触发
同时对 Asp.Net core 2.0 MVC 应用程序 (cookie) 和 REST API (JWT) 进行身份验证