web-dev-qa-db-ja.com

ログインページにリダイレクトする代わりに、Web API認証が401を返すようにする

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アプリケーションにエラーが発生します。

15
vantian

カスタム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
});
2
peco

これは私のために働いたものです。

カスタム属性を作成する:

[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ステータスコードを送信します。

1
Sudarshan_SMD

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が返されます。

0
Kyle B

.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;
    }
0

リダイレクトを回避するために、StatusCodePageミドルウェアを構成する必要がありました

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    app.UseStatusCodePages();
    ...
}
0