c# - AspNet 用户声称丢失

标签 c# asp.net-mvc asp.net-identity identityserver4 claims

研究身份提供者的概念证明,需要帮助理解 aspnet 身份的一些细微差别,特别是与用户声明相关的。

我想要完成的事情:

1) 公开一个 MVC 应用程序,该应用程序提供对 2 个微服务之一的安全访问,这些微服务将公开体育和运动员数据。

2) 允许本地用户帐户和外部帐户(如 google 或 facebook auth)。

当前设置:

1) 利用 Identity Server 4 进行身份验证的 Asp.Net MVC 应用程序。

2) 两个 Web Api 2 网络服务(1 个用于运动,1 个用于运动员)。体育 API 不安全……即……开放 API。运动员 API 应该通过基于策略的授权来保护。

3) Identity Server 4 Web 应用程序,通过 IdentityServer4 nuget 包利用 Entity Framework 和 ASP.NET Identity。

4) SQL Server 数据库“完全”配置为 api 资源、身份资源、客户端、几个具有不同角色和声明的测试用户进行测试。

目前有效:

1)所有用户都可以登录(本地和谷歌)

2) 声明似乎按我的预期加载(仍在努力理解 Identity Server 数据模型中声明表的所有关系)。

3) MVC 应用程序显示 id_token、access_token、refresh_token,然后循环遍历用户的声明并显示它们。

什么不起作用:

1) 并非我认为应该在 mvc 应用程序中显示的所有声明都实际显示。

我的意思的例子:

1) 在下面的第一个屏幕截图中,您可以看到 given_name 和 family_name 作为用户“bob”的声明。这是在 MVC razor 中使用以下代码片段显示的:

enter image description here

@if (User.Identities.First().IsAuthenticated)
{
    <h1>Tokens:</h1>

    <dt>id token</dt>
    <dd>@await ViewContext.HttpContext.GetTokenAsync("id_token")</dd>

    <dt>access token</dt>
    <dd>@await ViewContext.HttpContext.GetTokenAsync("access_token")</dd>

    <dt>refresh token</dt>
    <dd>@await ViewContext.HttpContext.GetTokenAsync("refresh_token")</dd>

    <br />

    <h1>Claims:</h1>
    <dl>
        @foreach (var claim in User.Claims)
        {
            <dt>@claim.Type : @claim.Value</dt>
        }
    </dl>
}

2) 在第二个屏幕截图中,您可以看到身份服务器生成的访问 token 中包含的其他“声明”。例如,“permission”、“testing”、“role”、“testingroleclaim”和“oddball”。

enter image description here

除了这里和那里的一些部分之外,大部分代码直接来自 Identity Server 4 文档中的快速入门教程。根据我阅读的所有内容,为了包含自定义声明,您需要实现自己的 IProfileService 接口(interface)实例。我已经这样做了,它似乎按预期工作。这是代码和屏幕截图,显示了在调试器中加载的“其他”声明:

enter image description here

以下是数据库表及其条目:

1) 身份资源/身份声明:

enter image description here

2) ApiResources/ApiScopes/ApiScopeClaims

enter image description here

3) AspNetUsers/AspNetRoles/AspNetUserClaims/AspNetRoleClaims/etc

enter image description here

这是我的问题:

1) 为什么在 ProfileService::GetProfileDataAsync 方法中加载的声明没有包含在 MVC 显示的 User.Claims 列表中?

更新 1:

1) 我在 mvc 应用程序的客户端表上更新了 AlwaysIncludeUserClaimsInIdToken = True 。发生了以下事情: a) “oddball”声明现在显示在 MVC 声明列表的输出中。 b) MVC 应用程序中显示的声明现在包含在 id_token 中,但它们仍然不包含“其他”声明。
enter image description here

更新 2:

1)我想出了我原来问题的答案。过滤列表的原因是以下代码行将根据 RequestedClaimsType 属性中存在的声明类型进行内部过滤。现在我需要了解为什么该列表中只有“name”、“given_name”和“family_name”。此信息的来源:https://github.com/IdentityServer/IdentityServer4/blob/master/src/IdentityServer4/src/Extensions/ProfileDataRequestContextExtensions.cs
context.AddRequestedClaims(claims);

最佳答案

终于弄清楚我错过了什么。客户端应用程序负责在连接 openid 中间件时设置 OpenIdConnect 选项。选项对象的属性之一称为“ClaimActions”。这些声明操作允许客户端连接自定义映射属性。这是 ClaimsActions.MapJsonKey 属性/方法组合的文档:

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/additional-claims?view=aspnetcore-2.2#map-user-data-keys-and-create-claims

这是我添加到我的客户端启动类中的代码,以使其适用于一组自动序列化的声明。

services.AddAuthentication(options =>
{
   options.DefaultScheme = "Cookies";
   options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{                    
    options.SignInScheme = "Cookies";

    options.Authority = "http://localhost:5000";
    options.RequireHttpsMetadata = false;

    options.ClientId = "mvc";
    options.ClientSecret = "secret";
    options.ResponseType = "code id_token";

    options.SaveTokens = true;
    options.GetClaimsFromUserInfoEndpoint = true;

    options.Scope.Add("athlete.full");
    options.Scope.Add("rights");
    options.Scope.Add("email");
    options.Scope.Add("address");
    options.Scope.Add("phone");

    options.Scope.Add("offline_access");

    // These are what allowed the claims to be serialized for front-end consumption.
    options.ClaimActions.MapJsonKey(JwtClaimTypes.WebSite, "website");
    options.ClaimActions.MapJsonKey(JwtClaimTypes.Gender, "gender");
    options.ClaimActions.MapJsonKey(JwtClaimTypes.BirthDate, "birthdate");
});

关于c# - AspNet 用户声称丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57434260/

相关文章:

c# - 当它似乎被添加到项目时,引用丢失的错误

c# - C#示例将DynamicTemplates与NEST和ElasticSearch结合使用

c# - 将 Math.Round 结果转换为 float 是否安全?

c# - 如何在不使用asp.net mvc中的模型类的情况下从 View 下拉列表获取数据到 Controller

.net - 将 ASP.NET 身份与核心域模型解耦 - 洋葱架构

asp.net - .NET 身份电子邮件/用户名更改

c# - 分析期间出现未知函数 CoUninitializeE

asp.net-mvc - 从 HtmlHelper 扩展方法中传递的 lambda 表达式获取属性值的最简单方法是什么?

c# - 如何通过正则表达式验证mvc中的CNIC号

Asp.net 身份密码哈希