ユーザーがログインしていないときにASP.NET Core Identityが401を返すようにしようとしています。メソッドに[Authorize]
属性を追加し、401を返す代わりに302を返します。 services.Configure
およびapp.UseCookieAuthentication
をLoginPath
にnull
またはPathString.Empty
に設定するなど、多数の提案が機能しているようには見えません。
ASP.NET Core 2.xの時点:
services.ConfigureApplicationCookie(options =>
{
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
});
要求ヘッダーにX-Requested-With:XMLHttpRequestが含まれる場合、ステータスコードは302ではなく401になります
private static bool IsAjaxRequest(HttpRequest request)
{
return string.Equals(request.Query["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal) ||
string.Equals(request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal);
}
asp.net mvcコアの場合このインスタンスを使用
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
options.LogoutPath = new PathString("/Account/Logout");
options.Events.OnRedirectToLogin = context =>
{
if (context.Request.Path.StartsWithSegments("/api")
&& context.Response.StatusCode == StatusCodes.Status200OK)
{
context.Response.Clear();
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
}
context.Response.Redirect(context.RedirectUri);
return Task.CompletedTask;
};
});
services.Configure<IdentityOptions>(options =>
{
options.Cookies.ApplicationCookie.LoginPath = new PathString("/");
options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents()
{
OnRedirectToLogin = context =>
{
if (context.Request.Path.Value.StartsWith("/api"))
{
context.Response.Clear();
context.Response.StatusCode = 401;
return Task.FromResult(0);
}
context.Response.Redirect(context.RedirectUri);
return Task.FromResult(0);
}
};
});
ソース:
asp.netコアユニットテスト を詳しく調べたところ、ようやく実用的なソリューションが見つかりました。 services.AddIdentity
への呼び出しに次を追加する必要があります
services.AddIdentity<ApplicationUser, IdentityRole>(o => {
o.Cookies.ApplicationCookie.AutomaticChallenge = false;
});
Identity = Cookie認証を使用するASP.NET Core 3.x(プレビュー)の場合、これがトリックでした:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<IdentityContext>()
.AddDefaultTokenProviders()
.AddRoles<IdentityRole>();
services.ConfigureApplicationCookie(options =>
{
options.Events.OnRedirectToLogin = context =>
{
context.Response.Headers["Location"] = context.RedirectUri;
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
});
これは、さまざまなバリエーションで至る所に見られます。しかし、ここでの本質的なポイントは、ConfigureApplicationCookie
を指定する必要があることです[〜#〜] after [〜#〜]AddIdentity
。それは「悲しい」ですが、本当です。これは SOの答え 最終的に暗闇の中で光をもたらしました。
私は1日以上頭を擦って、さまざまなバリエーションを試しました:
ApplicationCookie
を設定します(ただし、AddIdentity
への呼び出しの前に動作しません。それはすべてうまくいきませんでした。しかし、上記の答えで、最終的に401 UnAuthorizedが返されました(これはUnAuthenticatedであるはずです)
ASP.NET Core 2.2.0の私にとっては、これだけが機能しました:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(
options =>
{
options.LoginPath = new PathString("/Account/Login");
options.LogoutPath = new PathString("/Account/Logout");
options.Events.OnRedirectToLogin = context =>
{
if (context.Request.Path.StartsWithSegments("/api")
&& context.Response.StatusCode == StatusCodes.Status200OK)
{
context.Response.Clear();
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
}
context.Response.Redirect(context.RedirectUri);
return Task.CompletedTask;
};
}
);