亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在控制器外部使用時,IHttpContextAccessor 包含空 User.Identity

在控制器外部使用時,IHttpContextAccessor 包含空 User.Identity

C#
拉莫斯之舞 2023-08-20 09:39:35
我正在編寫一個應用程序 ASP.Net Core (2.2) MVC。我需要根據登錄用戶的某些聲明的值過濾 DbContext 內的一些數據。我注入 IHttpContextAccessor,但是當我嘗試訪問 HttpContext.User.Identity 時 - 所有屬性均為 null,所有聲明均為空。這就是我試圖實現連接 IHttpContextAccessor 的方式。我使用這樣的標準方法:public void ConfigureServices(IServiceCollection services){  services.AddHttpContextAccessor();...}然后我構建一個自定義提供程序來從用戶中提取聲明:public class GetClaimsFromUser : IGetClaimsProvider{  public string UserId {get; private set;}  public GetClaimsFromUser(IHttpContextAccessor accessor)  {     UserId = accessor.HttpContext?.User.Claims.SingleOrDefault(x => x.Type == ClaimTypes.Name)?.Value;  }}然后我還將它注入到ConfigureServices方法中:public void ConfigureServices(IServiceCollection services){...  services.AddScoped<IGetClaimsProvider, GetClaimsFromUser>();...}之后,我將其注入到 ApplicationDbContext 中,并嘗試在構造函數中設置私有 _userId 字段:public class ExpenseManagerDbContext: IdentityDbContext<ApplicationUser>{  private string _userId;  public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IGetClaimsProvider claimsProvider) : base(options)  {    _userId = claimsProvider.UserId;    ...  }...}而這里卻是空的。當我訪問控制器內的 HttpContext 時,User.Identity 不為空,一切都很好。但是,當我需要在控制器外部訪問它時,它是空的。謝謝你的幫助?。?!完整的代碼可以在這里找到: https: //github.com/dudelis/expense-manager/blob/master/ExpenseManager.DataAccess/Concrete/EntityFramework/ExpenseManagerDbContext.cs?
查看完整描述

2 回答

?
郎朗坤

TA貢獻1921條經驗 獲得超9個贊

您正在嘗試訪問ExpenseManagerDbContext應用程序的IdentityDbContext. 因此,它本身是身份驗證系統的依賴項,并且將在框架執行身份驗證時得到解決。

所以流程有點像這樣:

  1. 請求進來了。

  2. 身份驗證中間件運行以對用戶進行身份驗證。

  3. UserManager解決了ExpenseManagerDbContext。

  4. ExpenseManagerDbContext解決了IGetClaimsProvider

  5. GetClaimsProvider解析 HttpContext 并嘗試訪問用戶的聲明。

  6. 身份驗證中間件執行身份驗證并設置HttpContext.User結果。

如果您查看步驟 5 和 6,您將看到在身份驗證中間件能夠實際對用戶進行身份驗證并更新上下文上的用戶對象之前訪問 HttpContext 。由于身份驗證中間件始終在請求開始時運行,因此情況始終如此。

我建議您重新考慮,ExpenseManagerDbContext因為它可能不應該依賴于當前登錄的用戶。它應該獨立于此。如果您的邏輯依賴于用戶 ID,那么它可能應該是一個單獨的服務。


查看完整回答
反對 回復 2023-08-20
?
慕萊塢森

TA貢獻1810條經驗 獲得超4個贊

解決了!問題在于 IdentityDbContext 和 ApplicationDataDbContext 共享相同的 DbContext。在我的控制器中,我有以下代碼:


[Authorize]

public class AccountController : Controller

{

  [HttpGet]

  public IActionResult Index()

  {

      var accounts = _accountService.GetAll();

      var models = _mapper.Map<List<AccountDto>>(accounts);

      return View(models);

   }

}

當我嘗試從瀏覽器調用控制器時,由于 [Authorize] 屬性,應用程序第一次初始化了 DbContext。這是在沒有任何 HttpContext 的情況下完成的。因此,當應用程序在“_accountService.GetAll()”中調用 DbContext 時,DbContext 已經實例化,并且沒有調用 Constructor 方法,因此,我的所有私有字段仍然為空!因此,我創建了第二個 DbContext 類,僅用于身份驗證/授權目的。


public class ApplicationDbAuthContext : IdentityDbContext

{

    public ApplicationDbAuthContext(DbContextOptions<ApplicationDbAuthContext> options) : base(options)

    {

    }

}

因此,在控制器內發出請求期間,當我進行調用時會實例化正確的 DbContext,并且它包含 HttpContext。


我將更新存儲庫中的代碼以顯示更改。同時,感謝您的所有回答。


查看完整回答
反對 回復 2023-08-20
  • 2 回答
  • 0 關注
  • 222 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號