Identity Server 3 - Ajax 调用 401 而不是 302
Identity Server 3 - 401 on Ajax Calls instead of 302
我有一个网络 api / mvc 混合应用程序,我已将其配置为使用 cookie 身份验证。这适用于应用程序的 mvc 部分。网络 api 确实强制执行授权,但它没有返回 401 - Unauthorised
而是 returns 和 302 - Found
并重定向到登录页面。我宁愿returns一个401
。我试图连接到 CookieAuthenticationProvider.OnApplyRedirect
委托,但这似乎没有被调用。我错过了什么?我当前的设置如下:
AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject;
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
ExpireTimeSpan = TimeSpan.FromMinutes(20),
SlidingExpiration = true,
CookieHttpOnly = true,
CookieSecure = CookieSecureOption.Never, //local non ssl-dev only
Provider = new CookieAuthenticationProvider
{
OnApplyRedirect = ctx =>
{
if (!IsAjaxRequest(ctx.Request))
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = IdentityConfig.Authority,
ClientId = IdentityConfig.SoftwareClientId,
Scope = "openid profile roles",
RedirectUri = IdentityConfig.RedirectUri,
ResponseType = "id_token",
SignInAsAuthenticationType = "Cookies"
});
在您的示例中,UseCookieAuthentication
不再控制它,而 UseOpenIdConnectAuthentication
控制它。这涉及使用 Notifications
属性 和拦截 OpenID Connect 身份验证请求。
尝试以下方法获得灵感:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = IdentityConfig.Authority,
ClientId = IdentityConfig.SoftwareClientId,
Scope = "openid profile roles",
RedirectUri = IdentityConfig.RedirectUri,
ResponseType = "id_token",
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = notification =>
{
if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.AuthenticationRequest)
{
if (IsAjaxRequest(notification.Request) && notification.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
notification.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
notification.HandleResponse();
return Task.FromResult(0);
}
}
return Task.FromResult(0);
}
}
});
在我的例子中,IsAjaxRequest 没有起到作用。相反,我依赖于所有到 WebAPI 的路由都在“/api”下,所以我做的不是 IsAjaxRequest:
RedirectToIdentityProvider = context => {
if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication){
if (context.Request.Path.StartsWithSegments(new PathString("/api")) && context.Response.StatusCode == (int)HttpStatusCode.Unauthorized){
context.HandleResponse();
return Task.CompletedTask;
}
}
return Task.CompletedTask;
}
我有一个网络 api / mvc 混合应用程序,我已将其配置为使用 cookie 身份验证。这适用于应用程序的 mvc 部分。网络 api 确实强制执行授权,但它没有返回 401 - Unauthorised
而是 returns 和 302 - Found
并重定向到登录页面。我宁愿returns一个401
。我试图连接到 CookieAuthenticationProvider.OnApplyRedirect
委托,但这似乎没有被调用。我错过了什么?我当前的设置如下:
AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject;
JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
ExpireTimeSpan = TimeSpan.FromMinutes(20),
SlidingExpiration = true,
CookieHttpOnly = true,
CookieSecure = CookieSecureOption.Never, //local non ssl-dev only
Provider = new CookieAuthenticationProvider
{
OnApplyRedirect = ctx =>
{
if (!IsAjaxRequest(ctx.Request))
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = IdentityConfig.Authority,
ClientId = IdentityConfig.SoftwareClientId,
Scope = "openid profile roles",
RedirectUri = IdentityConfig.RedirectUri,
ResponseType = "id_token",
SignInAsAuthenticationType = "Cookies"
});
在您的示例中,UseCookieAuthentication
不再控制它,而 UseOpenIdConnectAuthentication
控制它。这涉及使用 Notifications
属性 和拦截 OpenID Connect 身份验证请求。
尝试以下方法获得灵感:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = IdentityConfig.Authority,
ClientId = IdentityConfig.SoftwareClientId,
Scope = "openid profile roles",
RedirectUri = IdentityConfig.RedirectUri,
ResponseType = "id_token",
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
RedirectToIdentityProvider = notification =>
{
if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.AuthenticationRequest)
{
if (IsAjaxRequest(notification.Request) && notification.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
notification.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
notification.HandleResponse();
return Task.FromResult(0);
}
}
return Task.FromResult(0);
}
}
});
在我的例子中,IsAjaxRequest 没有起到作用。相反,我依赖于所有到 WebAPI 的路由都在“/api”下,所以我做的不是 IsAjaxRequest:
RedirectToIdentityProvider = context => {
if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication){
if (context.Request.Path.StartsWithSegments(new PathString("/api")) && context.Response.StatusCode == (int)HttpStatusCode.Unauthorized){
context.HandleResponse();
return Task.CompletedTask;
}
}
return Task.CompletedTask;
}