我正在尝试使用 React Web 应用程序设置 C#,使用 C# 后端作为 Backend-For-Frontend,这样我就可以使用 cookie 身份验证。我有点遵循本教程,但使用最新的 C#/React 模板。
我可以使身份验证正常工作,但如果我尝试使用
[Authorize]
属性访问端点,我会收到指向 /Account/Login?ReturnUrl=(...)
的 302 重定向。如果还没有有效的身份验证 cookie,我希望它是 401。
这是开发者工具(Edge)中网络选项卡的屏幕截图:
我的身份验证是在
Program.cs
类中注册的,如下所示:
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(o =>
{
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
o.Cookie.SameSite = SameSiteMode.Strict;
o.Cookie.HttpOnly = true;
})
.AddOpenIdConnect("Auth0", options => AuthenticationExtensions.ConfigureOpenIdConnect(options, configuration));
AuthenticationExtensions.ConfigureOpenIdConnect()
看起来像这样。我尝试添加所有不同的事件,我可以想象与重定向有什么关系,但似乎都没有效果:
internal static void ConfigureOpenIdConnect(OpenIdConnectOptions options, IConfiguration configuration)
{
options.Authority = $"https://{configuration["Auth0:Domain"]}";
options.ClientId = configuration["Auth0:ClientId"];
options.ClientSecret = configuration["Auth0:ClientSecret"];
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.ResponseMode = OpenIdConnectResponseMode.FormPost;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("offline_access");
options.CallbackPath = new PathString("/callback");
options.ClaimsIssuer = "Auth0";
options.SaveTokens = true;
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProviderForSignOut = (context) =>
{
var logoutUri = $"https://{configuration["Auth0:Domain"]}/v2/logout?client_id={configuration["Auth0:ClientId"]}";
var postLogoutUri = context.Properties.RedirectUri;
if (!string.IsNullOrEmpty(postLogoutUri))
{
if (postLogoutUri.StartsWith("/"))
{
// transform to absolute
var request = context.Request;
postLogoutUri = request.Scheme + "://" + request.Host + request.PathBase + postLogoutUri;
}
logoutUri += $"&returnTo={Uri.EscapeDataString(postLogoutUri)}";
}
context.Response.Redirect(logoutUri);
context.HandleResponse();
return Task.CompletedTask;
},
// I would expect one of these to work, but they don't.
OnRedirectToIdentityProvider = context => {
context.Response.StatusCode = 401;
context.HandleResponse();
return Task.CompletedTask;
},
OnAuthenticationFailed = context => {
context.Response.StatusCode = 401;
context.HandleResponse();
return Task.CompletedTask;
},
OnAccessDenied = context => {
context.Response.StatusCode = 401;
context.HandleResponse();
return Task.CompletedTask;
}
};
}
我在 Cookie Auth 中遇到了这个问题。我通过覆盖这些事件解决了这个问题。
builder.Services
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(config =>
{
config.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
return Task.CompletedTask;
};
config.Events.OnRedirectToAccessDenied = context =>
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
return Task.CompletedTask;
};
});