AuthenticateResult.Principal 尝试通过 Google 进行身份验证时为 null

问题描述 投票:0回答:2

我试图允许用户在我的 ASP.NET Core Blazor 应用程序上使用其 Google 帐户登录。每当我进入我的 app/login/google-login 时,一切都会按预期进行。我被重定向到谷歌的登录页面,我可以选择一个帐户来登录。选择我的帐户后,加载需要几秒钟,然后 Visual Studio 2019 告诉我:

System.NullReferenceException: 'Object reference not set to an instance of an object.' Microsoft.AspNetCore.Authentication.AuthenticateResult.Principal.get returned null.

在这段代码中:

var claims = response.Principal.Identities.FirstOrDefault().Claims.Select(claim => new
                    {
                        claim.Issuer,
                        claim.OriginalIssuer,
                        claim.Type,
                        claim.Value
                    });

一些调试揭示了以下内容:

{"succeeded":false,"ticket":null,"principal":null,"properties":null,"failure":null,"none":true}

这是我从 Google API 得到的响应,格式为 JSON。基本上它告诉我主体为空,我可以猜到,但其余部分也为空。这里发生了什么?这是否只是我在 Google 端的范围的问题?我有理由相信这不是问题,因为我的应用程序应该能够处理任何 API 响应而不会崩溃,对吗?

这是我的 LoginController.cs 类:

[AllowAnonymous, Route("login")]
    public class LoginController : Controller
    {
        [Route("google-login")]
        public IActionResult GoogleLogin()
        {
            var properties = new AuthenticationProperties { RedirectUri = Url.Action("GoogleResponse") };
            return Challenge(properties, GoogleDefaults.AuthenticationScheme);
        }

        [Route("google-response")]
        public async Task<IActionResult> GoogleResponse()
         {
            var response = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);

            var claims = response.Principal.Identities.FirstOrDefault().Claims.Select(claim => new
                {
                    claim.Issuer,
                    claim.OriginalIssuer,
                    claim.Type,
                    claim.Value
                });

            return Json(claims);
        }
    }

这是我的 Startup.cs:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            //services.AddSingleton<WeatherForecastService>();

            services.AddDbContext<Context>(options => options.UseSqlServer(Configuration.GetConnectionString("Context")));
            services.AddIdentity<User, Role>().AddEntityFrameworkStores<Context>();

            services.AddHttpContextAccessor();
            services.AddScoped<IReservationService, ReservationService>();
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.LoginPath = "/login/google-login";
            })
            .AddGoogle(options =>
            {
                options.ClientId = Configuration["Google:ClientID"];
                options.ClientSecret = Configuration["Google:ClientSecret"];
            });
        }

        // 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.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();

                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
        }
    }

如果您需要任何其他信息或代码,我很乐意尽快提供。

c# asp.net-core oauth-2.0 blazor nullreferenceexception
2个回答
1
投票

这条线可以说是我项目中相当大的一部分,它阻止了与 Google 的通信,谁知道什么原因。

services.AddIdentity<User, Role>().AddEntityFrameworkStores<Context>();

我现在基本上只是继续没有 UserManager 和 RoleManager,只是编写手动方法来访问 AspNetUsers 等。

可能不是真正的解决方案,但它就是这样。


0
投票

来晚了,但最近遇到了同样的错误。我有这个日志:

The cookie 'idsrv.external' has set 'SameSite=None' and must also set 'Secure'.

我发现如果cookie设置了SameSite=None,回调Url必须是https才能接收来自Google的Cookie。因为您的应用程序没有 Cookie,所以无法通过以下行进行授权:

var properties = new AuthenticationProperties { RedirectUri = Url.Action("GoogleResponse") };

将开发者 URL 更改为 https 将解决此问题。 示例:https://localhost:5000

© www.soinside.com 2019 - 2024. All rights reserved.