web-dev-qa-db-ja.com

MVC 5アクセスクレームアイデンティティユーザーデータ

私はMVC 5 WebアプリケーションをEntity Framework 5 Database Firstアプローチを使って開発しています。ユーザーの認証にOWINを使用しています。以下は私のアカウントコントローラ内の私のログイン方法を示しています。

public ActionResult Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        var user = _AccountService.VerifyPassword(model.UserName, model.Password, false);
        if (user != null)
        {
            var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, model.UserName), }, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);

            identity.AddClaim(new Claim(ClaimTypes.Role, "guest"));
            identity.AddClaim(new Claim(ClaimTypes.GivenName, "A Person"));
            identity.AddClaim(new Claim(ClaimTypes.Sid, user.userID)); //OK to store userID here?

            AuthenticationManager.SignIn(new AuthenticationProperties
            {
                IsPersistent = model.RememberMe
            }, identity);

            return RedirectToAction("Index", "MyDashboard");
        }
        else
        {
            ModelState.AddModelError("", "Invalid username or password.");
        }
    }
    // If we got this far, something failed, redisplay form
    return View(model);
}

ご覧のとおり、ClaimsIdentityを作成し、それに複数のクレームを追加してから、次のようにしてOWINに渡します。 サインインを実行するためのAuthenticationManager

私が抱えている問題は、私のアプリケーションの残りの部分で、コントローラまたはRazorビューのいずれかでクレームにアクセスする方法がわからないことです。

このチュートリアルにリストされている方法を試してみました

http://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/

たとえば、Claimsに渡された値にアクセスしようとして、私のControllerコードでこれを試しましたが、user.Claimsはnullです。

var ctx = HttpContext.GetOwinContext();
ClaimsPrincipal user = ctx.Authentication.User;
IEnumerable<Claim> claims = user.Claims;

多分私はここで何かが足りない。

UPDATE

Darinの答えに基づいて、私は彼のコードを追加しました、それでも私は主張へのアクセスを見ていません。下のスクリーンショットを見て、identity.overの上に置いたときに見たものを見てください。

enter image description here

103
tcode

これを試して:

[Authorize]
public ActionResult SomeAction()
{
    var identity = (ClaimsIdentity)User.Identity;
    IEnumerable<Claim> claims = identity.Claims;
    ...
}
150
Darin Dimitrov

またこれをすることができます:

//Get the current claims principal
var identity = (ClaimsPrincipal)Thread.CurrentPrincipal;
var claims = identity.Claims;

更新

コメントに従ってさらなる説明を提供する。

次のようにシステム内にユーザーを作成しているとします。

UserManager<applicationuser> userManager = new UserManager<applicationuser>(new UserStore<applicationuser>(new SecurityContext()));
ClaimsIdentity identity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);

あなたは自動的にあなたのアイデンティティに関連したいくつかのクレームを埋めておくべきです。

ユーザー認証後にカスタマイズしたクレームを追加するには、次のようにします。

var user = userManager.Find(userName, password);
identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));

Darinが上で答えたように、あるいは私が持っているように、主張は読み返すことができます。

以下のIDを渡して電話をかけても、請求は保持されます。

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = persistCookie }, identity);
32
hutchonoid

私は自分が必要とするものを見るために私自身の拡張クラスを作ります、それで私が私のコントローラや私のViewに必要なとき、私は私の名前空間に次のようなものを使うだけを追加します

public static class UserExtended
{
    public static string GetFullName(this IPrincipal user)
    {
        var claim = ((ClaimsIdentity)user.Identity).FindFirst(ClaimTypes.Name);
        return claim == null ? null : claim.Value;
    }
    public static string GetAddress(this IPrincipal user)
    {
        var claim = ((ClaimsIdentity)user.Identity).FindFirst(ClaimTypes.StreetAddress);
        return claim == null ? null : claim.Value;
    }
    public ....
    {
      .....
    }
}

私のコントローラでは:

using XXX.CodeHelpers.Extended;

var claimAddress = User.GetAddress();

私のかみそりで:

@using DinexWebSeller.CodeHelpers.Extended;

@User.GetFullName()
25
Jesus Padilla

クレームを常に使用したくない場合は、これが代替方法です。これを見てください チュートリアル by Ben Foster。

public class AppUser : ClaimsPrincipal
{
    public AppUser(ClaimsPrincipal principal)
        : base(principal)
    {
    }

    public string Name
    {
        get
        {
            return this.FindFirst(ClaimTypes.Name).Value;
        } 
    }

}

その後、ベースコントローラを追加することができます。

public abstract class AppController : Controller
{       
    public AppUser CurrentUser
    {
        get
        {
            return new AppUser(this.User as ClaimsPrincipal);
        }
    }
}

あなたのコントローラでは、あなたがするだろう:

public class HomeController : AppController
{
    public ActionResult Index()
    {
        ViewBag.Name = CurrentUser.Name;
        return View();
    }
}
16
Quentin

Darinの答えについてさらに触れるために、あなたはあなたの特定の主張を使用することによって得ることができます FindFirst 方法:

var identity = (ClaimsIdentity)User.Identity;
var role = identity.FindFirst(ClaimTypes.Role).Value;
10
Eric Bridges

これもできます。

IEnumerable<Claim> claims = ClaimsPrincipal.Current.Claims;
10
angularsen

@ Rosdi Kasimの答えの最短かつ簡略化されたバージョンは

string claimvalue = ((System.Security.Claims.ClaimsIdentity)User.Identity).
    FindFirst("claimname").Value;

Claimnameはあなたが検索したいクレームです、すなわちあなたが "StreedAddress"クレームを探しているならば、上記の答えはこのようになります

string claimvalue = ((System.Security.Claims.ClaimsIdentity)User.Identity).
    FindFirst("StreedAddress").Value;
6
noman zafar
Request.GetOwinContext().Authentication.User.Claims

ただし、特にStartup.Auth.csのregenerateIdentityが有効になっている場合は、 "GenerateUserIdentityAsync"メソッド内にクレームを追加することをお勧めします。

6
Basil Banbouk

IEnumerableを問い合わせるためにはsystem.linqを参照する必要があることを忘れないでください。
それはあなたにするのに必要な拡張オブジェクトをあなたに与えるでしょう:

CaimsList.FirstOrDefault(x=>x.Type =="variableName").toString();
5

ControllerBaseクラスによると、アクションを実行しているユーザーの要求を受け取ることができます。

enter image description here

これが1行でできることです。

var claims = User.Claims.ToList();
2
conterio
var claim = User.Claims.FirstOrDefault(c => c.Type == "claim type here");
1
Felipe Deveza