重定向时 Google 身份验证的 ASP .NET Core CORS 问题

发布于 2025-01-14 12:36:13 字数 3999 浏览 7 评论 0原文

一直遵循此教程,以便在我的 Web API 和客户端上实现 Google 身份验证侧面(使用 React 和 axios 执行请求)身份验证过程因 CORS 问题而中断,我正在努力解决它:

访问“https://accounts.google.com/o/oauth2/v2/auth?(etc)”处的 XMLHttpRequest(从“https://localhost:44320/Photo/b997d788-3812-41d0-”重定向)来自来源“https://localhost:8080”的 a09d-1a597eee9bad') 已被 CORS 策略阻止:否请求的资源上存在“Access-Control-Allow-Origin”标头。

这是 Startup.cs 文件:

namespace rvc
{
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.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddDefaultPolicy(builder =>
            {
                builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
            });
        });
        
        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        }).AddCookie(options =>
        {
            options.LoginPath = "/account/google-login";
        }).AddGoogle(options =>
        {
            options.ClientId = "clientId";
            options.ClientSecret = "secret";
        });
        
        services.AddScoped<PhotoService>();
        services.AddScoped<TagService>();
        services.AddScoped(_ => new BlobServiceClient(Configuration.GetConnectionString("AzureBlobStorage")));
        services.AddDbContext<Data.DataContext>(x => x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddControllers().AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
        });
        services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "rvc", Version = "v1" }); });
    }

    // 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();
            app.UseSwagger();
            app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "rvc v1"));
        }

        app.UseHttpsRedirection();

        if (env.IsProduction())
        {
            app.UseSpa(spa => { });

            app.UseFileServer(new FileServerOptions
            {
                FileProvider = new PhysicalFileProvider(
                    Path.Combine(env.ContentRootPath, "client")),
                EnableDefaultFiles = true
            });
        }

        app.UseRouting();
        app.UseCors();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
    }
}
}

调用 Route("google-login") 但未到达 Url.Action("GoogleResponse")。这些是 Google 身份验证方法:

namespace rvc.Controllers;

[AllowAnonymous, Route("account")]
public class AccountController : 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 result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);

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

    return Json(claims);
}
}

Been following this tutorial in order to implement Google authentication in my web API but on the client side (using React and axios to do the request) the authentication process gets interrupted with this CORS issue and I'm struggling to sort it out:

Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/auth?(etc)' (redirected from 'https://localhost:44320/Photo/b997d788-3812-41d0-a09d-1a597eee9bad') from origin 'https://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This is the Startup.cs file:

namespace rvc
{
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.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddDefaultPolicy(builder =>
            {
                builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
            });
        });
        
        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        }).AddCookie(options =>
        {
            options.LoginPath = "/account/google-login";
        }).AddGoogle(options =>
        {
            options.ClientId = "clientId";
            options.ClientSecret = "secret";
        });
        
        services.AddScoped<PhotoService>();
        services.AddScoped<TagService>();
        services.AddScoped(_ => new BlobServiceClient(Configuration.GetConnectionString("AzureBlobStorage")));
        services.AddDbContext<Data.DataContext>(x => x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddControllers().AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
        });
        services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "rvc", Version = "v1" }); });
    }

    // 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();
            app.UseSwagger();
            app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "rvc v1"));
        }

        app.UseHttpsRedirection();

        if (env.IsProduction())
        {
            app.UseSpa(spa => { });

            app.UseFileServer(new FileServerOptions
            {
                FileProvider = new PhysicalFileProvider(
                    Path.Combine(env.ContentRootPath, "client")),
                EnableDefaultFiles = true
            });
        }

        app.UseRouting();
        app.UseCors();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
    }
}
}

The Route("google-login") gets called but the Url.Action("GoogleResponse") is not reached. These are the Google Authentication methods:

namespace rvc.Controllers;

[AllowAnonymous, Route("account")]
public class AccountController : 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 result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);

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

    return Json(claims);
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

停顿的约定 2025-01-21 12:36:13

这可能是因为您在服务器上使用了重定向,这会触发 CORS(即使您在服务器上允许这样做)。
您必须以其他方式将重定向 URL 返回到前端,从前端应用程序捕获它,然后调用您需要调用的 URL。

This is probably because from the server you use redirect, which triggers CORS (even if from your server you allow it).
you have to return the redirect URL to your front-end in some other way, capture it from the front-end app and then call the URL you need to invoke.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文