.NET Core 2.0身份和jwt?

Zac*_*Zac 5 c# asp.net asp.net-mvc jwt asp.net-core

我一直在寻找并尝试对.NET Core身份进行更多研究(https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.1&tabs=visual -studio%2Caspnetcore2x)和Jwt(json网络令牌)。我一直在使用.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核心标识和JWT可以共存吗?还是我必须选择一个?我有MVC和网络api,并希望同时保护两者。

小智 7

是的你可以。逻辑过程在这个方法中:

第 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);
    }
    
    Run Code Online (Sandbox Code Playgroud)

第 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);
    }
Run Code Online (Sandbox Code Playgroud)

第 3 步:然后返回您的方法,您必须生成并返回 JWT 令牌

jwt = await jwtFactory.GenerateEncodedToken(userName, identity);
return new OkObjectResult(jwt);
Run Code Online (Sandbox Code Playgroud)
  • 要生成令牌,请执行以下操作:

    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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

有很多方法可以做到这一点。最常见的是:Validate Identity User --> Get User identifiers --> Generate and Return Token based on Identifiers --> Use Authorization for endpoints

希望这有帮助


Nev*_*ane 4

您可以验证用户名和密码并生成 Jwt。

首先,确保您的API在startup.cs中设置了以下默认身份:

services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(
        Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>();
Run Code Online (Sandbox Code Playgroud)

其次,您可以使用如下方式验证登录:

您可以设置一个 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在 get 函数中,您现在可以生成 Jwt。