我正在使用Entity Framework 5 Database First方法开发MVC 5 Web应用程序.我正在使用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并向其添加多个声明,然后使用AuthenticationManager将其传递给OWIN以执行登录.
我遇到的问题是,我不确定如何在控制器或Razor视图中访问我的应用程序的其余部分中的声明.
我曾尝试过本教程中列出的方法
http://brockallen.com/2013/10/24/a-primer-on-owin-cookie-authentication-middleware-for-the-asp-net-developer/
例如,我在我的Controller代码中尝试了这一点,试图访问传递给Claims的值,但是,user.Claims等于null
var ctx = HttpContext.GetOwinContext(); ClaimsPrincipal user = ctx.Authentication.User; IEnumerableclaims = user.Claims;
也许我在这里遗漏了一些东西.
UPDATE
根据Darin的回答,我添加了他的代码,但我仍然看不到索赔的访问权限.请看下面的截图,显示我在身份上盘旋时看到的内容.声明.
你也可以这样做:
//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已经回答上述问题或正如我所说的那样,索赔可以回读.
当您在下面通过以下身份致电时,声明会保留:
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = persistCookie }, identity);
我创建自己的扩展类来查看我需要的东西,所以当我需要进入我的控制器或我的视图时,我只将这个使用添加到我的命名空间:
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()
试试这个:
[Authorize] public ActionResult SomeAction() { var identity = (ClaimsIdentity)User.Identity; IEnumerable<Claim> claims = identity.Claims; ... }
如果您不想一直使用声明,则可以选择此选项.看看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(); } }
请记住,为了查询IEnumerable,您需要引用system.linq.
它将为您提供所需的扩展对象:
CaimsList.FirstOrDefault(x=>x.Type =="variableName").toString();
Request.GetOwinContext().Authentication.User.Claims
但是,最好在"GenerateUserIdentityAsync"方法中添加声明,尤其是在启用Startup.Auth.cs中的regenerateIdentity时.
你也可以这样做.
IEnumerable<Claim> claims = ClaimsPrincipal.Current.Claims;
要进一步了解Darin的答案,您可以使用FindFirst方法获取您的具体声明:
var identity = (ClaimsIdentity)User.Identity; var role = identity.FindFirst(ClaimTypes.Role).Value;
@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;