wake-up-neo.com

MVC 5 Access Claims Identity-Benutzerdaten

Ich entwickle eine MVC 5-Webanwendung mit Entity Framework 5 Database First Ansatz. Ich verwende [~ # ~] owin [~ # ~] für die Authentifizierung von Benutzern. Unten sehen Sie meine Anmeldemethode in meinem Account Controller.

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

Wie Sie sehen, erstelle ich eine ClaimsIdentity , füge ihr mehrere Ansprüche hinzu und übergebe sie dann an [~ # ~] Hiermit können Sie [~ # ~] mithilfe des Authentifizierungsmanagers die Anmeldung durchführen.

Das Problem, das ich habe, ist, dass ich nicht sicher bin, wie ich auf die Ansprüche im Rest meiner Anwendung zugreifen soll, entweder in Controllern oder in Razor Views.

Ich hatte den in diesem Tutorial aufgeführten Ansatz ausprobiert

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

Ich habe dies beispielsweise in meinem Controller-Code versucht, um Zugriff auf die Werte zu erhalten, die an die Ansprüche übergeben wurden. Der Benutzer.Claims ist jedoch gleich null

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

Vielleicht fehlt mir hier etwas.

[~ # ~] Update [~ # ~]

Basierend auf Darins Antwort habe ich seinen Code hinzugefügt, aber ich sehe immer noch keinen Zugang zu den Ansprüchen. In der Abbildung unten sehen Sie, was ich sehe, wenn ich den Mauszeiger über die Identität halte.

enter image description here

105
tcode

Versuche dies:

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

Sie können dies auch tun:

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

pdate

Zur weiteren Erläuterung laut Kommentar.

Wenn Sie Benutzer in Ihrem System wie folgt erstellen:

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

Sie sollten automatisch einige Ansprüche in Bezug auf Ihre Identität ausfüllen lassen.

So fügen Sie benutzerdefinierte Ansprüche hinzu, nachdem sich ein Benutzer authentifiziert hat:

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

Die Behauptungen können wieder ausgelesen werden, wie Darin oben geantwortet hat oder wie ich.

Die Ansprüche bleiben bestehen, wenn Sie unten anrufen und die Identität weitergeben in:

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

Ich erstelle meine eigene erweiterte Klasse, um zu sehen, was ich brauche. Wenn ich also in meinem Controller oder in meiner Ansicht etwas brauche, füge ich meinem Namespace nur das using hinzu:

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 ....
    {
      .....
    }
}

In meinem Controller:

using XXX.CodeHelpers.Extended;

var claimAddress = User.GetAddress();

In meinem Rasierer:

@using DinexWebSeller.CodeHelpers.Extended;

@User.GetFullName()
29
Jesus Padilla

Dies ist eine Alternative, wenn Sie Ansprüche nicht immer verwenden möchten. Schauen Sie sich dieses Tutorial von Ben Foster an.

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

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

}

Dann können Sie einen Basiscontroller hinzufügen.

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

In Ihrem Controller würden Sie Folgendes tun:

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

Um die Antwort von Darin weiter zu berühren, können Sie zu Ihren spezifischen Ansprüchen gelangen, indem Sie die FindFirst Methode:

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

Sie können dies auch tun.

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

kürzeste und vereinfachte Version von @Rosdi Antwort von Kasim ist

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

Claimname ist der Anspruch, den Sie abrufen möchten, d. h., wenn Sie nach dem Anspruch "StreedAddress" suchen, lautet die obige Antwort folgendermaßen

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

Es ist jedoch besser, die Ansprüche in die "GenerateUserIdentityAsync" -Methode einzufügen, insbesondere wenn "regenerateIdentity" in "Startup.Auth.cs" aktiviert ist.

6
Basil Banbouk

Denken Sie daran, dass Sie zum Abfragen der IEnumerable auf system.linq verweisen müssen.
Sie erhalten das Erweiterungsobjekt, das Sie für Folgendes benötigen:

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

Gemäß der ControllerBase-Klasse können Sie die Ansprüche für den Benutzer abrufen, der die Aktion ausführt.

enter image description here

hier ist, wie Sie es in 1 Zeile tun können.

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