Entity framework 正在获取当前用户Blazor webassembly的用户ID

Entity framework 正在获取当前用户Blazor webassembly的用户ID,entity-framework,asp.net-core,blazor,blazor-client-side,blazor-webassembly,Entity Framework,Asp.net Core,Blazor,Blazor Client Side,Blazor Webassembly,因此,我正在编写一个Blazor webassembly应用程序,使用asp.ner核心标识。我需要获取当前用户的ID,而不是Identity中的方法提供的用户名 方法 上下文。User.identity.name 提供用户名,但我需要模型/表格中fk的ID 我无法使用用户名,因为用户名可能会更改 我已经在网上搜索过了,但是我一直只看到返回的用户名 非常感谢您的任何帮助。我将此用于锅炉板标识服务器: @page "/claims" @inject Authentication

因此,我正在编写一个Blazor webassembly应用程序,使用asp.ner核心标识。我需要获取当前用户的ID,而不是Identity中的方法提供的用户名

方法

上下文。User.identity.name

提供用户名,但我需要模型/表格中fk的ID

我无法使用用户名,因为用户名可能会更改

我已经在网上搜索过了,但是我一直只看到返回的用户名


非常感谢您的任何帮助。

我将此用于锅炉板标识服务器:

@page "/claims"
@inject AuthenticationStateProvider AuthenticationStateProvider

<h3>ClaimsPrincipal Data</h3>

<p>@_authMessage</p>

@if (_claims.Count() > 0)
{
    <table class="table">
        @foreach (var claim in _claims)
        {
            <tr>
                <td>@claim.Type</td>
                <td>@claim.Value</td>
            </tr>
        }
    </table>
}

<p>@_userId</p>

@code {
    private string _authMessage;       
    private string _userId;
    private IEnumerable<Claim> _claims = Enumerable.Empty<Claim>();

    protected override async Task OnParametersSetAsync()
    {
        await GetClaimsPrincipalData();
        await base.OnParametersSetAsync();
    }

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            _authMessage = $"{user.Identity.Name} is authenticated.";
            _claims = user.Claims;
            _userId = $"User Id: {user.FindFirst(c => c.Type == "sub")?.Value}";
        }
        else
        {
            _authMessage = "The user is NOT authenticated.";
        }
    }
}
@page”/claims
@注入AuthenticationStateProvider AuthenticationStateProvider
索赔资料
@_authMessage

@如果(_claims.Count()>0) { @foreach(var索赔在_索赔中) { @索赔.类型 @索赔价值 } } @_用户ID

@代码{ 私有字符串authMessage; 私有字符串_userId; private IEnumerable_claims=Enumerable.Empty(); 受保护的重写异步任务OnParametersSetAsync() { 等待GetClaimsPrincipalData(); 等待base.OnParametersSetAsync(); } 专用异步任务GetClaimsPrincipalData() { var authState=等待AuthenticationStateProvider.GetAuthenticationStateAync(); var user=authState.user; if(user.Identity.IsAuthenticated) { _authMessage=$“{user.Identity.Name}已通过身份验证。”; _索赔=用户索赔; _userId=$“用户Id:{User.FindFirst(c=>c.Type==“sub”)?.Value}”; } 其他的 { _authMessage=“用户未通过身份验证。”; } } }
我将其用于锅炉板标识服务器:

@page "/claims"
@inject AuthenticationStateProvider AuthenticationStateProvider

<h3>ClaimsPrincipal Data</h3>

<p>@_authMessage</p>

@if (_claims.Count() > 0)
{
    <table class="table">
        @foreach (var claim in _claims)
        {
            <tr>
                <td>@claim.Type</td>
                <td>@claim.Value</td>
            </tr>
        }
    </table>
}

<p>@_userId</p>

@code {
    private string _authMessage;       
    private string _userId;
    private IEnumerable<Claim> _claims = Enumerable.Empty<Claim>();

    protected override async Task OnParametersSetAsync()
    {
        await GetClaimsPrincipalData();
        await base.OnParametersSetAsync();
    }

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            _authMessage = $"{user.Identity.Name} is authenticated.";
            _claims = user.Claims;
            _userId = $"User Id: {user.FindFirst(c => c.Type == "sub")?.Value}";
        }
        else
        {
            _authMessage = "The user is NOT authenticated.";
        }
    }
}
@page”/claims
@注入AuthenticationStateProvider AuthenticationStateProvider
索赔资料
@_authMessage

@如果(_claims.Count()>0) { @foreach(var索赔在_索赔中) { @索赔.类型 @索赔价值 } } @_用户ID

@代码{ 私有字符串authMessage; 私有字符串_userId; private IEnumerable_claims=Enumerable.Empty(); 受保护的重写异步任务OnParametersSetAsync() { 等待GetClaimsPrincipalData(); 等待base.OnParametersSetAsync(); } 专用异步任务GetClaimsPrincipalData() { var authState=等待AuthenticationStateProvider.GetAuthenticationStateAync(); var user=authState.user; if(user.Identity.IsAuthenticated) { _authMessage=$“{user.Identity.Name}已通过身份验证。”; _索赔=用户索赔; _userId=$“用户Id:{User.FindFirst(c=>c.Type==“sub”)?.Value}”; } 其他的 { _authMessage=“用户未通过身份验证。”; } } }
在Startup.cs中,在ConfigureServices中添加以下行

services.AddHttpContextAccessor();
在Blazor组件中,在文件顶部添加以下行

@using System.Security.Claims
@inject IHttpContextAccessor HttpContextAccessor
在方法中,添加以下行以获取UserId

var principal = HttpContextAccessor.HttpContext.User;
var loggedInUserId = principal.FindFirstValue(ClaimTypes.NameIdentifier);

在Startup.cs中,在ConfigureServices中添加以下行

services.AddHttpContextAccessor();
在Blazor组件中,在文件顶部添加以下行

@using System.Security.Claims
@inject IHttpContextAccessor HttpContextAccessor
在方法中,添加以下行以获取UserId

var principal = HttpContextAccessor.HttpContext.User;
var loggedInUserId = principal.FindFirstValue(ClaimTypes.NameIdentifier);

不是答案,只是关于使用断点查找答案的提示。我的站点是Blazor服务器,所以很可能情况有所不同——在我的情况下,Brian Parker的解决方案不适合我,所以我做了以下工作:

var user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
if (true) {} // or any other code here, breakpoint this line
如果在检索用户后立即设置断点,运行应用程序并在中断时将用户变量悬停在代码中,它将弹出完整的对象。通过悬停各个字段,您可以进行调查。我发现索赔类型字符串是大而长的东西,比如“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"

因此,对我有效的答案是:

var user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
string userId = user.FindFirst(c => c.Type.Contains("nameidentifier"))?.Value;
我的观点是,当文档很复杂时,或者当技术变化很快,以至于一天的正确答案是第二天的错误线索时,你可以通过使用VS进行挖掘来实现很多


希望这对某人有帮助D

不是答案,只是关于使用断点查找答案的提示。我的站点是Blazor服务器,所以很可能情况有所不同——在我的情况下,Brian Parker的解决方案不适合我,所以我做了以下工作:

var user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
if (true) {} // or any other code here, breakpoint this line
如果在检索用户后立即设置断点,运行应用程序并在中断时将用户变量悬停在代码中,它将弹出完整的对象。通过悬停各个字段,您可以进行调查。我发现索赔类型字符串是大而长的东西,比如“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"

因此,对我有效的答案是:

var user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
string userId = user.FindFirst(c => c.Type.Contains("nameidentifier"))?.Value;
我的观点是,当文档很复杂时,或者当技术变化很快,以至于一天的正确答案是第二天的错误线索时,你可以通过使用VS进行挖掘来实现很多


希望这对某人有帮助D

我建议在控制器中提取Id,因为这比信任客户端发布内容更安全。@ErikThysell这是该原则的扩展方法。我建议在控制器中提取Id,因为这比信任客户端发布内容更安全。@ErikThysell这是该原则的一种扩展方法。这在Blazor服务器dotnet 5上做得很好这在Blazor服务器dotnet 5上做得很好