web-dev-qa-db-ja.com

ASP.NET Core-ユーザーへのロール要求の追加

私は(.NET Frameworkに基づく)ASP.NET CoreでWindows認証を使用しています。ポイントは、そのユーザーにロールクレームを追加する必要があり、このロールは遠くのデータベースに格納されていることです。

OWIN/Cookie/UserManager/UserStore/Identityなどについて多くのことを読んだので、迷っています。

質問:アプリケーション全体に対してログインしている現在のユーザー(Windows)のロールクレームを最も簡単な方法で追加するにはどうすればよいですか?

[Authorize(Role= "MyAddedRole")]またはbool res = User.IsInRole("MyAddedRole")を簡単に使用する必要があります

ありがとう

12
Arnaud F.

自分に答えるので、私がしたこと:

自分のUserClaimStoreを作成します(このストアのみが必要で、他のストアは必要ありません)。

_public class MyIdentityStore :
    IUserClaimStore<IdentityUser>
{
    private MyDbContext _myDbContext;
    private bool _disposed = false; 

    public MyIdentityStore(MyDbContext myDbContext)
    {
        _myDbContext = myDbContext;
    }

    #region IUserClaimStore
    public Task<IList<Claim>> GetClaimsAsync(IdentityUser user, CancellationToken cancellationToken)
    {
        // logic here to retrieve claims from my own database using _myDbContext
    }

    // All other methods from interface throwing System.NotSupportedException.
    #endregion

    #region IDisposable Support

    protected virtual void Dispose(bool disposing)
    { /* do cleanup */ }
    #endregion
}
_

次に、独自のClaimTransformerを作成しました。

_public class MyClaimsTransformer : IClaimsTransformer
{
    private UserManager<IdentityUser> _userManager;

    public MyClaimsTransformer(UserManager<IdentityUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
    {
        var identity = ((ClaimsIdentity)context.Principal.Identity);

        // Accessing the UserClaimStore described above
        var claims = await _userManager.GetClaimsAsync(new IdentityUser(identity.Name));
        identity.AddClaims(claims);

        return await Task.FromResult(context.Principal);
    }
}
_

最後に、Startup.csで:

_    public void ConfigureServices(IServiceCollection services)
    {
        /* All other stuff here */ 

        // Adding Database connection
        services.AddDbContext<MyDbContext>(o => /* my options */);

        // Associates our database and store to identity
        services.AddIdentity<IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores<MyDbContext>()
            .AddUserStore<MyIdentityStore>();

        // Claims transformation from database to claims
        services.AddTransient<IClaimsTransformer, MyClaimsTransformer>();
    }


    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        /* All other stuff here */ 

        app.UseIdentity();

        app.UseClaimsTransformation(async (context) =>
        { // Retrieve user claims from database
            IClaimsTransformer transformer = context.Context.RequestServices.GetRequiredService<IClaimsTransformer>();
            return await transformer.TransformAsync(context);
        });
    }
_

そして今、私は[Authorize(Roles = "MyRole")]またはUser.IsInRole("MyRole")またはUser.HasClaim(/* */)さえ自由に使用できます!

8
Arnaud F.

答えのほかに、asp .netコアで完全に事前定義されている答えを見つけました。クレームを追加する場合:

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, UserName),
    new Claim(ClaimTypes.Role, "User"),
    new Claim(ClaimTypes.Role, "Admin"),
    new Claim(ClaimTypes.Role, Watever)
};

その後、あなたは言ったようにそれを使うことができます:

[Authorize(Roles = "Watever")]

または

User.IsInRole("Watever")
5
ashk hp

DB(AspNetRoles)に新しいロールを追加して、それをユーザー(AspNetUserRoles)に割り当てることができます。

1
vhr

あなたが話している ser オブジェクトには複数の Identities があり、それらはすべて複数の Claims を持つことができます。

ユーザーオブジェクトにカスタムクレームを追加する1つの方法は、選択した認証/承認フレームワーク(OAuthなど)によって自動的に作成されるIDを編集することであり、そのステップは明らかに各フレームワークに固有です。要約すると、そのフレームワークのドキュメントを読んで、どの時点でIDが作成され、カスタムコードで新しいクレームが追加されてそのポイントが拡張されているかがわかります。

別の、おそらくより簡単な方法は、新しいIdentityオブジェクト(すべての追加クレームを保持する)を作成し、 AddIdentity()method を使用して、ユーザーのIDリストに追加することです。

User.Claimsにアクセスすると、その列挙はUserオブジェクトにあるすべてのIDからのすべての要求を返します。

したがって、アプリケーションコードのどこにいても(最も適切な点は、ミドルウェアの一種だと思います)、次のようなことができます。

var myIdentity = new ClaimsIdentity(new []
{
    new Claim("claim type", "claim value"), 
    new Claim("claim type", "claim value"), 
    new Claim("claim type", "claim value"), 
});

context.User.AddIdentity(myIdentity);

それ以降は、User.Claimsを呼び出すたびに、Userオブジェクトの元のすべてのクレームと追加のクレームが返されます。

0
Mladen B.