【问题标题】:.NET Core 2.0 Identity AND jwt?.NET Core 2.0 身份和 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,并希望保护两者。

【问题讨论】:

标签: c# asp.net asp.net-mvc asp.net-core jwt


【解决方案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;
      }
      

    有很多方法可以做到这一点。 最常见的是: 验证身份用户 --> 获取用户标识符 --> 根据标识符生成并返回令牌 --> 对端点使用授权

    希望有帮助

    【讨论】:

      猜你喜欢
      • 2018-06-22
      • 2018-04-01
      • 2018-03-01
      • 2018-03-24
      • 2018-01-28
      • 2018-03-13
      • 2018-07-03
      • 2020-05-30
      • 2020-09-23
      相关资源
      最近更新 更多