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