【发布时间】:2021-06-22 09:04:35
【问题描述】:
我有一个 Blazor WASM 托管解决方案,该解决方案分为几个项目。客户端显然是客户端 WASM,服务器是托管 API 控制器的服务器端,数据是我的数据访问,具有 DataContext、存储库、迁移、应用程序用户等,然后是完全只是模型的模型。它使用身份作为其身份验证/授权
我想要完成的是两件事
1:我想在每次保存更新时记录用户 ID。
public async Task<Country> CreateAsync(Country country)
{
try
{
var addedEntity = _dataContext.Countries.Add(country);
await _dataContext.SaveChangesAsync();
return addedEntity.Entity;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in CreateAsync()");
throw;
}
}
在这里id喜欢做country.CreatedBy = userId; (这是在数据项目中)如何获取用户信息?为了访问这部分代码,他们必须获得授权。这是控制器操作,该控制器由 [Authorize] 属性管理
public async Task<IActionResult> Create(Country country)
{
if (country == null)
{
return BadRequest();
}
try
{
var createdCountry = await _repository.CreateAsync(country);
return CreatedAtAction("GetById", new { id = createdCountry.Id }, createdCountry);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Create() - Returning Internal Server Error");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
我还希望能够在控制器级别访问用户 ID(这是在服务器项目中)。我最终想添加更多日志并将 UserId 包含在日志中。
这是我的数据上下文
public class DataContext : ApiAuthorizationDbContext<ApplicationUser>
{
public DataContext(DbContextOptions options, IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
**db sets omitted**
}
- 在我的客户端项目中,我还希望能够访问组件中的 UserId 以进行日志记录。这是我的 App.razor 使用 CascadingAuthenticationState
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(BBQFriend.Components.PageComponents.Index).Assembly }">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
@if (!context.User.Identity.IsAuthenticated)
{
<RedirectToLogin />
}
else
{
<p>You are not authorized to access this resource.</p>
}
</NotAuthorized>
<Authorizing>
<Loading />
</Authorizing>
</AuthorizeRouteView>
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<div class="content">
<div class="section-title">
<h1>I think you're lost...</h1>
<div class="section-title-stripe"></div>
</div>
</div>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
在我的组件中我可以
[Inject]
public AuthenticationStateProvider AuthenticationStateProvider { get; set; }
protected override async Task OnInitializedAsync()
{
var authenticationState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
}
可以从 AuthenticationState 访问用户,但是我只能从 authenticationState.User.Identity.Name 获取名称,但我想获取 UserId。我可以将 UserId 添加到身份中,还是有办法在客户端获取 UserId?这是在客户端项目中,所以我没有任何像 UserManager 或 SigninManager 这样的身份类,它们在服务器上。
更新 1 我试过添加 services.AddHttpContextAccessor();到 Server Startup.cs ConfigureServices 方法并尝试在 Repository 级别(在 Data 项目中)使用 DI
public IngredientRepository(DataContext dataContext, ILogger<IngredientRepository> logger, IHttpContextAccessor httpContextAccessor)
{
_dataContext = dataContext ?? throw new ArgumentNullException(nameof(dataContext));
_logger = logger;
_httpContextAccessor = httpContextAccessor;
if(_httpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
{
userName = _httpContextAccessor.HttpContext.User.Identity.Name;
userId = _httpContextAccessor.HttpContext.User.FindFirst(c => c.Type == "sub")?.Value;
}
}
此上下文中的身份是 IsAuthenticated = True 但不包含有关用户的信息。没有声明、角色、名称等。
【问题讨论】:
标签: asp.net-identity blazor webassembly