【问题标题】:How to extend IdentityUser as a claim in ASP.NET Core / MVC 6 / EF7?如何在 ASP.NET Core / MVC 6 / EF7 中将 IdentityUser 扩展为声明?
【发布时间】:2016-08-17 12:25:03
【问题描述】:

我正在构建一个包含属于某个帐户的用户的网站。帐户由 AccountId 标识,它是数据库中大多数数据的外键,例如 Charges(与帐户相关联)或 Receipts(与帐户相关联)。

每次需要轮询存储库以获取数据以获取用户的 AccountId 时,我都想将 AccountId 添加为声明,而不是访问数据库。目标是做类似的事情:

_repository.GetAllChargesByAccountId(User.Identity.GetAccountId());

我只找到了一些花絮和部分解决方案,我无法解决这些示例与我的特定环境(ASP.NET Core RC1、MVC 6、EF7)之间的一些差异。

我从 IdentityUser 派生了一个类,用于添加关于用户的属性:

public class UserIdentity : IdentityUser {
    public static object Identity { get; internal set; }
    public int AccountId { get; set; }
}

我创建了一个派生自我用于我的 EF 用户存储的 IdentityDbContext 的 UserIdentityContext。

我有以下 AuthController:

public class AuthController : Controller {
    private SignInManager<UserIdentity> _signInManager;

    public AuthController(SignInManager<UserIdentity> signInManager) {
        _signInManager = signInManager;
    }

    public IActionResult Login() {
        if (User.Identity.IsAuthenticated)
            return RedirectToAction("Dashboard", "App");

        return View();
    }

    [HttpPost]
    public async Task<ActionResult> Login(LoginViewModel vm, string returnUrl) {
        if (ModelState.IsValid) {
            var signInResult = await _signInManager.PasswordSignInAsync(vm.Username, vm.Password, true, false);
            if (signInResult.Succeeded) {
                if (String.IsNullOrWhiteSpace(returnUrl))
                    return RedirectToAction("Dashboard", "App");
                else return RedirectToAction(returnUrl);
            } else {
                ModelState.AddModelError("", "Username or password is incorrect.");
            }
        }   

        return View();
    }

    public async Task<IActionResult> Logout() {
        if (User.Identity.IsAuthenticated) {
            await _signInManager.SignOutAsync();
        }

        return RedirectToAction("Index", "App");
    }
}

查看其他帖子,听起来我需要添加一个 IdentityExtension 才能以 User.Identity.GetAccountId() 的身份访问声明并生成自定义用户身份,如此答案:How to extend available properties of User.Identity 但显然已经完成在旧版本中,许多方法调用不再适用。

提前感谢您的任何回答或指导。

【问题讨论】:

标签: asp.net-core asp.net-identity asp.net-core-mvc entity-framework-core


【解决方案1】:

如果您为 AccountId 添加了声明,则可以轻松编写扩展方法来获取它:

public static string GetAccountId(this ClaimsPrincipal principal)
{
    if (principal == null)
    {
        throw new ArgumentNullException(nameof(principal));
    }
    var claim = principal.FindFirst("AccountId");
    return claim != null ? claim.Value : null;
}

如果您需要有关如何添加自定义声明的帮助,请参阅 this question

【讨论】:

  • 谢谢乔。扩展看起来很简单。让我看看您引用的问题,看看它们是否解决了索赔部分。我立即看到的差距是第一个问题创建了一个声明,但为其分配了一个“真实”的通用值。对我来说,我需要为每个用户分配一个唯一的值,即 AccountId。所以我需要从用户存储库中提取它,但不知道如何从 ClaimsTransform 类中获取它。
  • 我立即注意到的一件事是,使用 TransformClaims 无法达到目的,因为它不会在 cookie 中存储任何其他属性。它仍然需要数据库命中才能在每个请求上获取 AccountId。我将尝试覆盖 ClaimsFactory。
  • 您对此进行了排序吗?想要做同样的事情!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多