英文:
ASP.NET with Google authentication throws error on callback: The oauth state was missing or invalid
问题
I can provide the translation for the code and text you've provided:
Program.cs
#region 配置服务
builder.Host.ConfigureLogging(builder => builder.AddDomainLogger());
builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "***", Version = "v1" });
});
// ... 添加一些服务
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => options.LoginPath = "/api/authorization/login")
.AddGoogle(options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.CallbackPath = "/api/authorization/google/signin";
options.ClientId = builder.Configuration["Authentication:Google:ClientId"];
options.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"];
options.Scope.Add("email"); // 用于获取主要电子邮件地址
options.Scope.Add("profile"); // 用于获取个人公共信息,如姓名、图片等。
});
#endregion
var app = builder.Build();
#region 配置应用程序
// ... 一些逻辑
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "***"));
}
app.UseAuthentication();
app.UseAuthorization();
app.UseHttpsRedirection();
app.MapControllers();
#endregion
GoogleAuthorizationController.cs
[Route("api/authorization/google")]
[ApiController]
public class GoogleAuthorizationController : ControllerBase
{
[HttpGet]
[Route("login")]
public Task LoginGoogle()
{
return HttpContext.ChallengeAsync(GoogleDefaults.AuthenticationScheme, new AuthenticationProperties()
{
RedirectUri = Url.Action("SignInGoogle")
});
}
[HttpGet]
[Route("signin")]
public async Task<IActionResult> SignInGoogle() // <- 无法达到这里
{
If you need further assistance or have more specific questions, feel free to ask.
英文:
I'm developing a cookie authentication application with the ability to authorize through a Google account. I have a UI in React v18 and an ASP.NET Core 6 Web API. I created a web app in console.cloud.google.com and got the app credentials.
Authentication process with Google:
- user sends request from UI to API to authorize through google (
.../google/login
endpoint); - the API redirects user to google authorization;
- after succeed authorization it sends user to
.../google/signin
endpoint (registered in google).
Well, 1 - 2 works well, but I have exception on callback endpoint after succeed authorization on google side. It's not inside my controller:
> Exception: The oauth state was missing or invalid.
> Unknown location
>
> Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
I cannot understand how to fix it. I tried to change sign in schemas, callback paths etc, but it was useless. Here is my code:
Program.cs
#region Configure services
builder.Host.ConfigureLogging(builder => builder.AddDomainLogger());
builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "***", Version = "v1" });
});
// ... adding some services
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => options.LoginPath = "/api/authorization/login")
.AddGoogle(options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.CallbackPath = "/api/authorization/google/signin";
options.ClientId = builder.Configuration["Authentication:Google:ClientId"];
options.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"];
options.Scope.Add("email"); // to get primary email address
options.Scope.Add("profile"); // to get personal public info like name, image etc.
});
#endregion
var app = builder.Build();
#region Configure app
// ... some logic
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "***"));
}
app.UseAuthentication();
app.UseAuthorization();
app.UseHttpsRedirection();
app.MapControllers();
#endregion
GoogleAuthorizationController.cs
[Route("api/authorization/google")]
[ApiController]
public class GoogleAuthorizationController : ControllerBase
{
[HttpGet]
[Route("login")]
public Task LoginGoogle()
{
return HttpContext.ChallengeAsync(GoogleDefaults.AuthenticationScheme, new AuthenticationProperties()
{
RedirectUri = Url.Action("SignInGoogle")
});
}
[HttpGet]
[Route("signin")]
public async Task<IActionResult> SignInGoogle() // <- it can't reach it
{
答案1
得分: 1
你不需要配置
options.CallbackPath = "/api/authorization/google/signin";
在你的配置中,options.CallbackPath
不是指向你的控制器/操作的路径。它只需要与你的第三方提供者(如Google等)中注册的路径相同。它指的是由身份验证中间件处理的唯一路径,而不是控制器路径,默认情况下是 signin-google
,当完成后,它将重定向回你的控制器。
英文:
You don't need to configure
options.CallbackPath = "/api/authorization/google/signin";
in your configuration, The options.CallbackPath
is not the path to your Controller/Action. It just must be the same as registered in your 3rd party provider (Google, or so...). It refers to a unique path handled by the auth middleware instead of controller, By default is signin-google
, It will redirect back to your controller when it's done.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论