2

我正在构建一个拥有属于某个帐户的用户的网站。该帐户由AccountId标识,该帐户是数据库中大多数数据的外键,如收费(与帐户关联)或收据(与帐户关联)。如何扩展IdentityUser作为ASP.NET Core/MVC 6/EF7中的声明?

每次存储库需要轮询数据以获取用户的AccountId时,我都不想打数据库,而是希望将AccountId添加为索赔。我们的目标是做这样的事情:

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

我发现只有花絮和部分解决方案,这和我没有能够解决这些例子和我的特定环境(ASP.NET核心RC1之间存在一些差异,MVC 6,EF7)。

我都来源于IdentityUser类添加有关用户属性:

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

我创建了从IdentityDbContext得出结论说我用我的EF用户存储一个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"); 
    } 
} 

观看其他文章,这听起来像我需要为访问索赔User.Identity.GetAccountId(添加IdentityExtension),并生成自定义用户身份在这个答案:How to extend available properties of User.Identity但显然这是在一个较旧的版本和许多方法调用不适用了。

在此先感谢您的任何答案或指导。

+0

帮助似乎很相似到这个问题http://stackoverflow.com/questions/36496135/store-custom-datas-in-identity-cookie/36498357#36498357 –

回答

0

如果你已经加入了索赔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

+0

谢谢乔。扩展看起来像是简单的部分。让我看看你提到的问题,看他们是否解决索赔部分。我立即看到的差距是,第一个问题创建了一个声明,但是给它分配了一个“真实”的通用值。对我而言,我需要为每个用户分配一个唯一的值AccountId。所以我需要从用户存储库中提取,但不知道如何从ClaimsTransform类中获取。 –

+0

我立即注意到的一件事是,使用TransformClaims会破坏目的,因为它不会在cookie中存储任何其他属性。它仍然需要数据库命中才能在每个请求上获取AccountId。我将尝试覆盖ClaimsFactory。 –

+0

您是否对此进行了排序?希望做同样的事情! – P456678