MVC 5访问声明身份用户数据

 拍友2502875873 发布于 2023-01-30 19:35

我正在使用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;
IEnumerable claims = user.Claims;

也许我在这里遗漏了一些东西.

UPDATE

根据Darin的回答,我添加了他的代码,但我仍然看不到索赔的访问权限.请看下面的截图,显示我在身份上盘旋时看到的内容.声明.

在此输入图像描述

9 个回答
  • 你也可以这样做:

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

    2023-01-30 19:35 回答
  • 我创建自己的扩展类来查看我需要的东西,所以当我需要进入我的控制器或我的视图时,我只将这个使用添加到我的命名空间:

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

    2023-01-30 19:35 回答
  • 试试这个:

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

    2023-01-30 19:35 回答
  • 如果您不想一直使用声明,则可以选择此选项.看看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();
        }
    }
    

    2023-01-30 19:35 回答
  • 请记住,为了查询IEnumerable,您需要引用system.linq.
    它将为您提供所需的扩展对象:

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

    2023-01-30 19:37 回答
  • Request.GetOwinContext().Authentication.User.Claims
    

    但是,最好在"GenerateUserIdentityAsync"方法中添加声明,尤其是在启用Startup.Auth.cs中的regenerateIdentity时.

    2023-01-30 19:37 回答
  • 你也可以这样做.

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

    2023-01-30 19:37 回答
  • 要进一步了解Darin的答案,您可以使用FindFirst方法获取您的具体声明:

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

    2023-01-30 19:37 回答
  • @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;
    

    2023-01-30 19:37 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有