web-dev-qa-db-ja.com

ログイン成功時にクレームを追加し、アプリケーションの別の場所で取得します

認証されたユーザーにクレームを割り当てるカスタムの方法を実装する際に支援が必要です。ログインに成功すると、

var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
        switch (result)
        {
            case SignInStatus.Success:
                //Get the user
                ApplicationUser user = UserManager.FindByEmail(model.Email);
                //Ends here
                ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
                AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);

UserIdを使用して、データストアからユーザーに関するロールやその他の情報を取得します。その後、ユーザーダッシュボードにリダイレクトする前に、電子メール、ロール、firstName、Lastname、性別などの情報を含むユーザーに関するクレームを追加する必要があります。これは私がそれをやろうとする方法ですが、問題はログインメソッドでクレームを追加した後でも、_loginPartialのカミソリビューでそれを取得できないことです

たとえば、このようにログイン部分で電子メールクレーム値を表示したい場合

var claims = ClaimsPrincipal.Current.Claims;
    var principal = (ClaimsPrincipal)Thread.CurrentPrincipal;
    var email = principal.Claims.Where(c => c.Type == ClaimTypes.Email).Select(c => c.Value).SingleOrDefault();

Nullを返します。

そのため、結果として、追加後は同じログイン方法でしかアクセスできませんが、アプリケーションのどこからでもアクセスできるようにする必要があります。これらの申し立てをアプリケーション全体のどこか他の場所で取得できるようにするための支援をお願いします。

ありがとうございました。

22
Josh

クレームを追加する必要がありますbefore login afterではありません。この例を考えてみましょう:

_public async Task<ActionResult> Login(LoginViewModel model,string returnUrl)
{
    var user = UserManager.Find(model.Email, model.Password);
    if(user!=null)
    {
        var ident = UserManager.CreateIdentity(user, 
            DefaultAuthenticationTypes.ApplicationCookie);
        ident.AddClaims(new[] {
            new Claim("MyClaimName","MyClaimValue"),
            new Claim("YetAnotherClaim","YetAnotherValue"),
        });
        AuthenticationManager.SignIn(
            new AuthenticationProperties() { IsPersistent = true }, 
            ident);
        return RedirectToLocal(returnUrl);
    }
    ModelState.AddModelError("", "Invalid login attempt.");
    return View(model);
}
_

サインイン中にクレームを挿入したので、どこにいてもクレームにアクセスできます。

_((ClaimsIdentity)User.Identity).FindFirst("MyClaimName");
_

また、ApplicationUser.GenerateUserIdentityAsync()メソッドにクレームを追加することもできます。このメソッドにクレームを追加すると、SignInManager.PasswordSignInAsync()メソッドを使用して、デフォルトのLoginアクションメソッドを変更せずにユーザーをサインインできます。

_public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        userIdentity .AddClaims(new[] {
            new Claim("MyClaimName","MyClaimValue"),
            new Claim("YetAnotherClaim","YetAnotherValue"),
        });
        return userIdentity;
    }
}
_
36

ID 2では、クレームプリンシパルファクトリを作成し、それを以下のようにスタートアップConfigureServicesに接続することにより、これは非常に異なる方法で行われます...

public class CustomClaimsPrincipalFactory : UserClaimsPrincipalFactory<IUser, IApplicationRole>
{
    public CustomClaimsPrincipalFactory(UserManager<IUser> userManager, RoleManager<IApplicationRole> roleManager,
                                                IOptions<IdentityOptions> optionsAccessor)
        : base(userManager, roleManager, optionsAccessor)
    {
    }

    public async override Task<ClaimsPrincipal> CreateAsync(IUser user)
    {
        var principal = await base.CreateAsync(user);

        // Add your claims here
        ((ClaimsIdentity)principal.Identity).AddClaims(new[] { new Claim(ClaimTypes.Email, user.Email),
                                                                new Claim(ClaimTypes.Gender, user.Gender),
                                                                new Claim(ClaimTypes.GivenName, user.FirstName),
                                                                new Claim(ClaimTypes.Surname, user.LastName)
                                                             });

        return principal;
    }
}

このようにAddIdentityを呼び出した直後にConfigureServicesに接続します...

         services.AddIdentity<IUser, IApplicationRole>()
         .AddDefaultTokenProviders();


        // Add Custom Claims processor
        services.AddScoped<IUserClaimsPrincipalFactory<IUser>, CustomClaimsPrincipalFactory>();

これに関する非常に良い記事があります...

https://www.codeguru.com/csharp/csharp/cs_misc/security/asp.net-core-and-claim-based-security.html

5
Hoots

次に、表示ページで

@(((ClaimsIdentity)User.Identity).FindFirstValue("firstName"))

認証されたユーザーfirstNameが表示されます。

ページの上部で次のパッケージをインポートします

@using Microsoft.AspNet.Identity
@using System.Security.Claims;
4
anand

ビューから_User.Identity_にアクセスできませんか?

ユーザーのクレームを取得するために、これは私にとってこれほど簡単です:

var identity = (ClaimsIdentity) User.Identity

そして、_identity.Claims_にアクセスし、LINQを使用して特定のクレームを取得します。

1
terbubbs

IdentityUserのClaimプロパティは、そのコレクションでICollectionを提供し、次のC#メソッドを呼び出すことができます。

    public string GetCustomClaimValue(ICollection<IdentityUserClaim> claimCollection, string customClaimType)
    {
        string claimValue = "";
        foreach (IdentityUserClaim claim in claimCollection)
        {
            if (claim.ClaimType == customClaimType)
            {
                claimValue = claim.ClaimValue;
                break;
            }
        }
        return claimValue;
    }
0
Uwe Köhler