it-swarm.com.de

Stellen Sie sicher, dass die Web-API-Authentifizierung 401 zurückgibt, anstatt zur Anmeldeseite umzuleiten

Ich habe eine Web-API mit OWIN-Authentifizierung in Web MVC. Ich verwende <authentication> in Web.Config für meine Web-MVC, damit sie zur Anmeldeseite umleitet.

<authentication mode="Forms">
    <forms name="WEB.AUTH" loginUrl="~/login" domain="" protection="All" 
    timeout="43200" path="/" requireSSL="false" slidingExpiration="true" />
</authentication>

Ich verwende das Attribut [System.Web.Http.Authorize], um meine Web-API zu autorisieren. Aber irgendwie ist die API, die zur Anmeldeseite umleitet, dieselbe wie meine MVC-App aufgrund der obigen Konfiguration.

ich möchte die Umleitungsfunktion für die Web-MVC beibehalten und 401 für die Web-API zurückgeben. Wie kann ich das erreichen? sollte ich ein benutzerdefiniertes Berechtigungsattribut für die Web-API erstellen?

--EDIT--

Ich habe die Antwort von diesem Beitrag gefunden SuppressDefaultHostAuthentication in WebApi.Owin unterdrückt auch die Authentifizierung außerhalb von webapi

Also füge ich einfach ein paar Zeilen in meinen Startup.cs ein. Ich hatte alle meine Controller mit einem "API" -Präfix Route konfiguriert.

HttpConfiguration config = new HttpConfiguration();
//..some OWIN configuration
app.Map("/api", inner =>
{
  inner.UseWebApi(config);
});

stellen Sie sicher, dass Sie app.Map() nach den Zeilen für die Web-API-Konfiguration einfügen. Andernfalls wird der MVC-Anwendung ein Fehler angezeigt.

11
vantian

Erstellen Sie eine benutzerdefinierte AuthorizeAttribute:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Unauthorized");
    }
}

Wenn Sie in Zukunft das web.config-Zeug überspringen und owin zum Einrichten Ihrer Authentifizierung verwenden, können Sie in Ihrem Startup.cs Folgendes tun:

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

Das hat bei mir funktioniert.

Ein benutzerdefiniertes Attribut erstellen:

[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);
    }
}

Verwenden Sie das Attribut in Ihrem Controller:

    [HttpDelete]
    [NoRedirectAuthorizeAttribute(Roles = "Admin")]
    [Route("api/v3/thingstodelete/{id=id}")]
    public IHttpActionResult DeleteThingToDelete(Guid id)
    {
      //delete code
    }

Hier wird nur die HandleUnauthorizedRequest-Methode von AuthorizeAttribute überschrieben. Anstatt also eine Weiterleitung (304) zur Anmeldeseite zu senden, senden wir den HTTP-Statuscode Forbidden (403).

0
Sudarshan_SMD

Um das Verhalten von IIS basierend auf einer durch URL definierten Konvention zu ändern, möchten Sie Ihre OWIN-Pipeline verzweigen. Sie können dies mit IApplicationBuilder.Map tun. Angenommen, eine statische config:

public void Configure(IApplicationBuilder app)
{
    ...
    app.Map("/api", HandleWebApiRequests);
    ...
}

private static void HandleWebApiRequests(IApplicationBuilder app)
{
    app.UseWebApi(config);
}

Die Methode Map verzweigt die Pipeline auf der Grundlage einer URL, die mit "/api" beginnt, in die Methode HandleWebApiRequests.

Dies sollte dazu führen, dass sich 401-Fehler wie erwartet verhalten und einfach 401 ohne Umleitung zurückgeben.

0
Kyle B

In .NET Core habe ich es so gelöst, 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

Ich musste die StatusCodePage-Middleware konfigurieren, um eine Umleitung zu vermeiden

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