简体   繁体   English

使用 .mapuniquejsonkey 时@context.user.identity.name 为空

[英]@context.user.identity.name is null when using .mapuniquejsonkey

I have an two applications, Blazor and IdentityServer.我有两个应用程序,Blazor 和 IdentityServer。 I noticed that inside of my Startup.cs file under ConfigureServices method options.ClaimActions.MapUniqueJsonKey("role","role") and inside my index.razor file I use @context.user.identity.name it returns null.我注意到在我的Startup.cs文件中的ConfigureServices method options.ClaimActions.MapUniqueJsonKey("role","role")和我的index.razor文件中我使用@context.user.identity.name它返回空值。 But when I comment that claimactions line out and replace it with the following:但是,当我评论claimactions并用以下内容替换它时:

options.TokenValidationParameters = new TokenValidationParameters
                    {
                        NameClaimType = "name"
                    };

                    options.UseTokenLifetime = false;

it will return the current user's email.它将返回当前用户的电子邮件。 Is there a reason why it only returns a value when I replace that claimactions.mapuniquejsonkey line with the code above?当我用上面的代码替换该claimactions.mapuniquejsonkey行时,是否有原因它只返回一个值? I am trying to understand why that is.我试图理解为什么会这样。 I saw on a documentation about TokenValidationParameters but still not understanding it like I would like to.我在有关TokenValidationParameters的文档中看到过,但仍然没有像我想的那样理解它。

When I have the line options.ClaimActions.MapUniqueJsonKey("role","role") it returns null:当我有行options.ClaimActions.MapUniqueJsonKey("role","role")它返回空值:

在此处输入图片说明

When I comment that line out and replace it with those two lines above:当我注释掉该行并将其替换为上面的两行时:

在此处输入图片说明

If you would like to see the full code please see below:如果您想查看完整代码,请参见以下内容:

Startup.cs : Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();


            services.AddSingleton(sp => new HttpClient { BaseAddress = new Uri("http://localhost:36626") }); // WebApi project

            services.AddTransient<IWeatherForecastServices, WeatherForecastServices>();

            services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)

                .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
                {
                    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.SignOutScheme = OpenIdConnectDefaults.AuthenticationScheme;

                    options.Authority = "https://localhost:5443"; // IdentityServer Project
                    options.ClientId = "interactive";
                    options.ClientSecret = "KEY";

                    options.ResponseType = "code";
                  
                    options.Scope.Add("profile"); // default scope
                    options.Scope.Add("scope2");
                    options.Scope.Add("roles");
                    options.Scope.Add("permissions");
                    options.Scope.Add("email");
                    options.ClaimActions.MapUniqueJsonKey("role", "role");

                  /*  options.TokenValidationParameters = new TokenValidationParameters
                      {
                         NameClaimType = "name"
                      };

                    options.UseTokenLifetime = false;  */

                    options.SaveTokens = true;
                    options.GetClaimsFromUserInfoEndpoint = true;
                   
                });

            services.AddScoped<TokenProvider>();

            services.AddCors(options =>
            {
                options.AddPolicy("Open", builder => builder.AllowAnyOrigin().AllowAnyHeader());
            }

            );
            
            services.AddAuthorization(options =>
            {
                options.AddPolicy(Policy.Policies.IsUser, 
              Policy.Policies.IsUserPolicy());
            });                     

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseCors("Open");

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
        }

Index.razor : Index.razor

Index.razor

<AuthorizeView Policy="@Policy.Policies.IsUser">
    <h3>Welcome, <b>@context.User.Identity.Name</b></h3>
    <p>You can only see this if you satisfy the IsUser policy.</p>
</AuthorizeView>

Config.cs from IdentityServer:来自 IdentityServer 的Config.cs

                .......
                new Client
                {
                    ClientId = "interactive",
                    ClientSecrets = { new Secret("KEY".Sha256()) },
                    RequirePkce = true,
                    AllowedGrantTypes = GrantTypes.Code,

                    RedirectUris = { "https://localhost:5445/signin-oidc", "https://localhost:44327/signin-oidc" },
                    FrontChannelLogoutUri = "https://localhost:5445/signout-oidc",
                    PostLogoutRedirectUris = { "https://localhost:5445/signout-callback-oidc" },
                    AlwaysIncludeUserClaimsInIdToken = true,
                    AllowOfflineAccess = true,
                    AllowedScopes = { "openid", "profile", "email" , "scope2" ,"weatherforecast-api","roles","permissions"}
                },
            };

The Name claim and the Role claim are mapped to default properties in the ASP.NET Core HTTP context. Name 声明和 Role 声明映射到 ASP.NET Core HTTP 上下文中的默认属性。 Sometimes it is required to use different claims for the default properties, or the name claim and the role claim do not match the default values.有时需要为默认属性使用不同的声明,或者名称声明和角色声明与默认值不匹配。 The claims can be mapped using the TokenValidationParameters property and set to any claim as required.可以使用 TokenValidationParameters 属性映射声明,并根据需要设置为任何声明。

The following code snippet illustrates the use of the TokenValidationParameters:以下代码片段说明了 TokenValidationParameters 的使用:

  options.TokenValidationParameters = new TokenValidationParameters
   {
     NameClaimType = "email", 
     RoleClaimType = "role"
   };

As you can see, the Name claim is mapped to the "email" field, though usually it'll be mapped to the "name" field.如您所见,Name 声明映射到“email”字段,但通常它会映射到“name”字段。

Note: As your settings request the profile scope ( options.Scope.Add("profile"); ), no additional claims mapping is required.注意:当您的设置请求配置文件范围( options.Scope.Add("profile"); )时,不需要额外的声明映射。 That is to say that NameClaimType = "name" is superfluous.也就是说NameClaimType = "name"是多余的。

Another way to get the user claims is to use the OpenID Connect User Info API.获取用户声明的另一种方法是使用 OpenID Connect 用户信息 API。 The ASP.NET Core client application uses the GetClaimsFromUserInfoEndpoint property to configure this. ASP.NET Core 客户端应用程序使用 GetClaimsFromUserInfoEndpoint 属性来配置它。 One important difference from the first settings, is that you must specify the claims you require using the MapUniqueJsonKey method, otherwise only the name, given_name and email standard claims will be available in the client application.与第一个设置的一个重要区别是,您必须使用 MapUniqueJsonKey 方法指定所需的声明,否则客户端应用程序中将只提供名称、给定名称和电子邮件标准声明。 The claims included in the id_token are mapped per default. id_token 中包含的声明是默认映射的。 This is the major difference to the first option.这是与第一个选项的主要区别。 You must explicitly define some of the claims you require:您必须明确定义一些您需要的声明:

   // YOU MUST HAVE THE FIRST LINE WITHOUT WHICH YOU'LL GET NULL VALUES
   options.GetClaimsFromUserInfoEndpoint = true;
   options.ClaimActions.MapUniqueJsonKey("preferred_username", 
                                       "preferred_username");
   options.ClaimActions.MapUniqueJsonKey("gender", "gender");
   options.ClaimActions.MapUniqueJsonKey("role","role");

Note: You should look for answers by me and by Brian Parker, related to authentication and authorization.注意:您应该寻找我和 Brian Parker 提供的有关身份验证和授权的答案。 We've answered many questions in WebAssembly and Blazor Server Apps.我们在 WebAssembly 和 Blazor 服务器应用程序中回答了许多问题。 These are not articles about the subject, but solutions we provided to developers, and they encompass many aspects of the subject, including custom claims, transformation of claims etc. Brian Parker, also have complete apps in Github...see it.这些不是关于该主题的文章,而是我们提供给开发人员的解决方案,它们涵盖了该主题的许多方面,包括自定义声明、声明转换等。Brian Parker 在 Github 中也有完整的应用程序......请看。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Context.User.Identity.Name在MVC 4中返回null - Context.User.Identity.Name returns null in MVC 4 Context.User.Identity.Name null 即使在用户身份验证之后 - Context.User.Identity.Name null even after user authentication in identity 为什么在Windows Form Hub上下文中Context.User.Identity.Name为null? - Why Context.User.Identity.Name is null in Windows Form Hub Context? 事件获取SqlDependency的火后获取Context.User.Identity.Name为空 - Getting Context.User.Identity.Name Null After Event Got Fire of SqlDependency 为什么SignalR Context.User.Identity.Name为空? - Why is SignalR Context.User.Identity.Name empty? 为什么Context.User.Identity.Name始终为空? - Why is Context.User.Identity.Name always empty? MVC3 @ C​​ontext.User.Identity.Name为空值 - MVC3 @Context.User.Identity.Name empty value 在asp.net mvc中,context.User.Identity.Name的用途是什么? - In asp.net mvc what is the use of context.User.Identity.Name? .NET 4.0-&gt; 4.5 Context.User.Identity.Name在窗体身份验证后不再设置(总是返回Windows用户名) - .NET 4.0 -> 4.5 Context.User.Identity.Name is no longer set after Forms Authenication (always returns Windows username) 登录后 'User.Identity.Name' 为 null,但使用 Sustainsys.Saml2.Mvc 集成时 'IsAuthenticated' 为 true - After logging in 'User.Identity.Name' is null, but 'IsAuthenticated' is true when using Sustainsys.Saml2.Mvc integration
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM