web-dev-qa-db-fra.com

Données utilisateur d'identité de revendications d'accès MVC 5

Je développe une application Web MVC 5 utilisant Entity Framework 5 Database First approche. J'utilise OWIN pour l'authentification des utilisateurs. Ci-dessous, ma méthode de connexion dans mon contrôleur de compte.

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

Comme vous pouvez le constater, je crée un ClaimsIdentity et y ajoute plusieurs revendications, puis je le passe à OWIN en utilisant le AuthenticationManager pour procéder à la connexion.

Le problème que je rencontre est que je ne suis pas sûr de savoir comment accéder aux revendications dans le reste de ma demande, que ce soit dans les contrôleurs ou dans Razor Views.

J'avais essayé l'approche décrite dans ce tutoriel

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

Par exemple, j’ai essayé cela dans le code de mon contrôleur pour tenter d’accéder aux valeurs transmises dans les revendications, mais user.Claims est égal à null.

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

Peut-être me manque quelque chose ici.

UPDATE

Sur la base de la réponse de Darin, j'ai ajouté son code mais je ne parviens toujours pas à voir l'accès aux réclamations. S'il vous plaît voir la capture d'écran ci-dessous montrant ce que je vois quand survolé identité.Claims.

enter image description here

105
tcode

Essaye ça:

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

Vous pouvez aussi faire ceci:

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

Mise à jour

Fournir des explications supplémentaires conformément aux commentaires.

Si vous créez des utilisateurs dans votre système, procédez comme suit:

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

Certaines réclamations devraient automatiquement être associées à votre identité.

Pour ajouter des revendications personnalisées après l'authentification d'un utilisateur, procédez comme suit:

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

Les affirmations peuvent être relues comme Darin a répondu ci-dessus ou comme moi.

Les revendications sont persistantes lorsque vous appelez ci-dessous en transmettant l'identité dans:

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

Je crée ma propre classe étendue pour voir ce dont j'ai besoin. Ainsi, lorsque j'ai besoin de ma manette ou de ma vue, j'ajoute simplement l'utilisation à mon espace de noms de la manière suivante:

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

Dans mon contrôleur:

using XXX.CodeHelpers.Extended;

var claimAddress = User.GetAddress();

Dans mon rasoir:

@using DinexWebSeller.CodeHelpers.Extended;

@User.GetFullName()
29
Jesus Padilla

C'est une alternative si vous ne voulez pas utiliser les revendications tout le temps. Jetez un oeil à ceci tutoriel par Ben Foster.

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

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

}

Ensuite, vous pouvez ajouter un contrôleur de base.

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

Dans votre contrôleur, vous feriez:

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

Pour approfondir la réponse de Darin, vous pouvez accéder à vos revendications spécifiques en utilisant le FindFirst méthode:

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

Vous pouvez aussi faire ça.

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

la version la plus courte et simplifiée de la réponse de @Rosdi Kasim est

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

Claimname est la demande que vous souhaitez récupérer, c'est-à-dire que si vous recherchez une demande "StreedAddress", la réponse ci-dessus sera comme ceci

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

Toutefois, il est préférable d’ajouter les revendications à l’intérieur de la méthode "GenerateUserIdentityAsync", en particulier si regenerateIdentity dans Startup.Auth.cs est activé.

6
Basil Banbouk

N'oubliez pas que pour interroger IEnumerable, vous devez faire référence à system.linq.
Cela vous donnera l’objet extension à faire:

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

Selon la classe ControllerBase, vous pouvez obtenir les revendications pour l'utilisateur qui exécute l'action.

enter image description here

voici comment vous pouvez le faire en 1 ligne.

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