私は(.NET Frameworkに基づく)ASP.NET CoreでWindows認証を使用しています。ポイントは、そのユーザーにロールクレームを追加する必要があり、このロールは遠くのデータベースに格納されていることです。
OWIN/Cookie/UserManager/UserStore/Identityなどについて多くのことを読んだので、迷っています。
質問:アプリケーション全体に対してログインしている現在のユーザー(Windows)のロールクレームを最も簡単な方法で追加するにはどうすればよいですか?
[Authorize(Role= "MyAddedRole")]
またはbool res = User.IsInRole("MyAddedRole")
を簡単に使用する必要があります
ありがとう
自分に答えるので、私がしたこと:
自分の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(/* */)
さえ自由に使用できます!
答えのほかに、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")
DB(AspNetRoles)に新しいロールを追加して、それをユーザー(AspNetUserRoles)に割り当てることができます。
あなたが話している 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オブジェクトの元のすべてのクレームと追加のクレームが返されます。