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
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.
Essaye ça:
[Authorize]
public ActionResult SomeAction()
{
var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;
...
}
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);
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()
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();
}
}
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;
Vous pouvez aussi faire ça.
IEnumerable<Claim> claims = ClaimsPrincipal.Current.Claims;
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;
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é.
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();
var claim = User.Claims.FirstOrDefault(c => c.Type == "claim type here");