web-dev-qa-db-fra.com

Faire que l'authentification de l'API Web renvoie 401 au lieu de rediriger vers la page de connexion

J'ai une API Web avec authentification OWIN dans Web MVC. J'utilise <authentication> dans Web.Config pour mon Web MVC afin qu'il soit redirigé vers la page de connexion.

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

J'utilise l'attribut [System.Web.Http.Authorize] pour autoriser mon API Web. Mais d'une manière ou d'une autre, l'API redirigeant vers la page de connexion est identique à mon application MVC en raison de la configuration ci-dessus.

ce que je veux faire est de continuer à rediriger la fonction pour le Web MVC tout en retournant 401 pour l'API Web. Comment puis-je atteindre cet objectif? dois-je créer un attribut d'autorisation personnalisé pour l'API Web?

--EDIT--

J'ai trouvé la réponse de cet article SuppressDefaultHostAuthentication dans WebApi.Owin supprimant également l'authentification en dehors de webapi

Donc, je viens d'ajouter quelques lignes dans mon Startup.cs. Tous mes contrôleurs ont été configurés avec un préfixe "api".

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

assurez-vous de mettre app.Map() après les lignes de configuration Web Api. Sinon, l'application MVC se trompera.

11
vantian

Créez une AuthorizeAttribute personnalisée:

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

Si, à l'avenir, vous omettez les éléments web.config et utilisez owin pour configurer votre authentification, vous pouvez dans votre Startup.cs faire:

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

C'est ce qui a fonctionné pour moi.

Création d'un attribut personnalisé:

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

En utilisant l'attribut dans votre contrôleur:

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

Ici, nous ne faisons que redéfinir la méthode HandleUnauthorizedRequest de AuthorizeAttribute . Ainsi, au lieu d’envoyer une redirection (304) à la page de connexion, nous envoyons le code d’état HTTP Forbidden (403).

0
Sudarshan_SMD

Afin de modifier le comportement de IIS en fonction d'une convention définie par une URL, vous souhaitez créer une branche pour votre pipeline OWIN. Vous pouvez le faire en utilisant IApplicationBuilder.Map. En supposant une config statique:

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

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

La méthode Map branche le pipeline vers la méthode HandleWebApiRequests en fonction d'une URL commençant par "/api".

Cela devrait faire en sorte que les erreurs 401 se comportent comme elles sont supposées le faire et renvoient simplement 401 sans redirection.

0
Kyle B

Dans .NET Core je l'ai résolu comme ça, 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
Oyvind Habberstad

J'avais besoin de configurer le middleware StatusCodePage pour éviter la redirection

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