Web MVCにOWIN認証を備えたWeb APIがあります。 Web MVCのWeb.Configで_<authentication>
_を使用しているため、ログインページにリダイレクトしています。
_<authentication mode="Forms">
<forms name="WEB.AUTH" loginUrl="~/login" domain="" protection="All"
timeout="43200" path="/" requireSSL="false" slidingExpiration="true" />
</authentication>
_
Web APIを認証するために_[System.Web.Http.Authorize]
_属性を使用しています。しかし、どういうわけか、上記の構成により、APIは私のMVCアプリと同じようにログインページにリダイレクトします。
私がやりたいのは、Web MVCの関数をリダイレクトし続けるが、Web APIの401を返すことです。どうすればこれを達成できますか? Web APIのカスタム認証属性を作成する必要がありますか?
-EDIT-
私はこの投稿から答えを見つけました WebApi.OwinのSuppressDefaultHostAuthenticationもwebapi外の認証を抑制します
そのため、_Startup.cs
_に数行追加するだけです。私はすべてのコントローラーを「api」プレフィックスルートで構成しました。
_HttpConfiguration config = new HttpConfiguration();
//..some OWIN configuration
app.Map("/api", inner =>
{
inner.UseWebApi(config);
});
_
web API構成行の後に必ずapp.Map()
を配置してください。そうしないと、MVCアプリケーションにエラーが発生します。
カスタムAuthorizeAttribute
を作成します。
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized");
}
}
将来、web.configの設定をスキップしてowinを使用して認証を設定する場合は、Startup.cs
行う:
var provider = new CookieAuthenticationProvider();
var originalHandler = provider.OnApplyRedirect;
provider.OnApplyRedirect = context =>
{
if (!context.Request.Uri.LocalPath.StartsWith(VirtualPathUtility.ToAbsolute("~/api")))
{
context.RedirectUri = new Uri(context.RedirectUri).PathAndQuery;
originalHandler.Invoke(context);
}
};
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
CookieName = FormsAuthentication.FormsCookieName,
LoginPath = new PathString("/Account/LogOn"),
ExpireTimeSpan = TimeSpan.FromMinutes(240),
Provider = provider
});
これは私のために働いたものです。
カスタム属性を作成する:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class NoRedirectAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
{
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Forbidden);
}
}
コントローラーで属性を使用する:
[HttpDelete]
[NoRedirectAuthorizeAttribute(Roles = "Admin")]
[Route("api/v3/thingstodelete/{id=id}")]
public IHttpActionResult DeleteThingToDelete(Guid id)
{
//delete code
}
AuthorizeAttribute のHandleUnauthorizedRequestメソッドをオーバーライドしています。したがって、ログインページにリダイレクト(304)を送信する代わりに、Forbidden(403)HTTPステータスコードを送信します。
IISがURLで定義された規則に基づいて動作する方法を変更するには、OWINパイプラインを分岐させます。これを行うには、IApplicationBuilder.Map
を使用します。静的config
:
public void Configure(IApplicationBuilder app)
{
...
app.Map("/api", HandleWebApiRequests);
...
}
private static void HandleWebApiRequests(IApplicationBuilder app)
{
app.UseWebApi(config);
}
Map
メソッドは、"/api"
で始まるURLに基づいて、パイプラインをHandleWebApiRequests
メソッドに分岐します。
これにより、401エラーが想定どおりに動作し、リダイレクトなしで単に401が返されます。
.NET Coreでは、Startup.csで次のように解決しました。
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.Strict;
options.Cookie.Name = "AuthCookie";
options.Events.OnRedirectToAccessDenied = UnAuthorizedResponse;
options.Events.OnRedirectToLogin = UnAuthorizedResponse;
})
....
}
internal static Task UnAuthorizedResponse(RedirectContext<CookieAuthenticationOptions> context)
{
context.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
return Task.CompletedTask;
}
リダイレクトを回避するために、StatusCodePageミドルウェアを構成する必要がありました
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseStatusCodePages();
...
}