web-dev-qa-db-ja.com

.NET Core 2.0 Identity AND jwt?

私は周りを見回して、.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アプリでは、デフォルトのIDを認証/承認として使用してきましたが、これまでのところ問題なく機能しています。

私はロードブロッキングに遭遇しており、それが.NET CoreのIDと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の承認サーバーとして機能する新しいサーバーを起動する必要がありますか?もしそうなら、私はそれをするつもりはありません(高すぎる)。

doがjwtで実行される場合、.NET Core IDコードはどうなりますか?それでそれは消えなければなりませんか?共存できる場合、IdentityでMVCページを、jwtでAPIエンドポイントを承認するにはどうすればよいですか?

これは自由回答式の質問だと思いますが、その核心は次のとおりです。

.NET Core IdentityとJWTは共存できますか?または、どちらか一方を選択する必要がありますか? MVCとWeb APIがあり、両方を保護したいと考えています。

5
Zac

はい、できます。ロジックプロセスはこのメソッドにあります。

ステップ1:GetUserClaims

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;
    }
    

これを行うには多くの方法があります。最も一般的なのは、IDユーザーの検証->ユーザー識別子の取得->識別子に基づいてトークンを生成して返す->エンドポイントに認証を使用する

この助けを願っています

4
Daniel Aguilar

ユーザー名とパスワードを検証し、Jwtを生成できます。

まず、startup.csでAPIに次のデフォルトIDが設定されていることを確認します。

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を生成できます。

4