访问索赔身份用户数据

我正在开发一个 MVC 5网络应用程序使用 实体框架5数据库优先的方法。我使用 Owen对用户进行身份验证。下面显示了 Account 控制器中的 Login 方法。

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

正如您所看到的,我正在创建一个 声明身份并向它添加几个声明,然后使用 认证管理器将其传递给 Owen以执行登录。

我遇到的问题是,我不确定如何在我的应用程序的其余部分访问索赔,无论是在控制器还是在剃刀视图。

我已经尝试了本教程中列出的方法

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

例如,我在 Controller 代码中尝试了这种方法,试图访问传递给 Clamings 的值,但是访问的是用户。声明等于空

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

也许我遗漏了什么。

更新

根据 Darin 的回答,我加入了他的代码但还是看不到索赔的权限。请看下面的屏幕截图,显示我看到什么时悬停在身份。索赔。

enter image description here

227513 次浏览

试试这个:

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

你也可以这样做:

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

您应该自动填充一些与您的 Identity 相关的声明。

要在用户进行身份验证后添加自定义声明,可以按照以下方式进行:

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

这些声明可以像达林上面回答的那样或者像我一样读出来。

如果你致电以下方面,将身份信息传递到:

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

你也可以这么做。

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

为了进一步了解 Darin 的答案,你可以使用 FindFirst方法得到你的具体主张:

var identity = (ClaimsIdentity)User.Identity;
var role = identity.FindFirst(ClaimTypes.Role).Value;
Request.GetOwinContext().Authentication.User.Claims

但是,最好在“ GenerateUserIdentityAsync”方法中添加声明,特别是在启动过程中再生身份时。启用了 Auth.cs。

如果您不想一直使用索赔,这是一种替代方法。看看本 · 福斯特的 教程

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

请记住,为了查询 IEnumable,您需要引用 system.linq。
它将为您提供执行以下操作所需的扩展对象:

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

我创建了自己的扩展类来查看我需要什么,所以当我需要进入控制器或视图时,我只在名称空间中添加了 use,如下所示:

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()

根据 ControllerBase 类,可以为执行操作的用户获取声明。

enter image description here

你可以用一行代码做到这一点。

var claims = User.Claims.ToList();

简短的@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;
var claim = User.Claims.FirstOrDefault(c => c.Type == "claim type here");

我在我的基本控制器中就是这样使用它的,只是为了方便使用而共享。

    public string GetCurrentUserEmail() {
var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;
var email = claims.Where(c => c.Type == ClaimTypes.Email).ToList();
return email[0].Value.ToString();
}


public string GetCurrentUserRole()
{
var identity = (ClaimsIdentity)User.Identity;
IEnumerable<Claim> claims = identity.Claims;
var role = claims.Where(c => c.Type == ClaimTypes.Role).ToList();
return role[0].Value.ToString();
}