2016-05-11 8 views
5

Nach den Dokumenten hier habe ich versucht, ein richtlinienbasiertes Auth-Schema zu implementieren. http://docs.asp.net/en/latest/security/authorization/policies.html#security-authorization-handler-exampleASP.NET 5 Policy-Based Authorization-Handle, das nicht aufgerufen wird

Ich stieß auf das Problem, dass meine Handle-Methode nicht auf meinem benutzerdefinierten AuthorizationHandler aufgerufen wurde. (Es wirft nicht hier). Es injiziert auch die Abhängigkeit, die sich derzeit im Konstruktor befindet.

Hier ist der AuthorizationHandler Code.

using WebAPIApplication.Services; 
using Microsoft.AspNet.Authorization; 

namespace WebAPIApplication.Auth 
{ 
    public class TokenAuthHandler : AuthorizationHandler<TokenRequirement>, IAuthorizationRequirement 
    { 
     private IAuthService _authService; 

     public TokenAuthHandler(IAuthService authService) 
     { 
      _authService = authService; 
     } 

     protected override void Handle(AuthorizationContext context, TokenRequirement requirement) 
     { 
      throw new Exception("Handle Reached"); 
     } 
    } 

    public class TokenRequirement : IAuthorizationRequirement 
    { 
     public TokenRequirement() 
     { 
     } 
    } 
} 

In Start Up I

// Authorization 
      services.AddSingleton<IAuthorizationHandler, TokenAuthHandler>() 
       .AddAuthorization(options => 
       { 
        options.AddPolicy("ValidToken", 
         policy => policy.Requirements.Add(new TokenRequirement())); 
       }); 

Die Controller-Methode ist

// GET: api/values 
     [HttpGet, Authorize(Policy="ValidToken")] 
     public string Get() 
     { 
      return "test"; 
     } 

Schlagen diesen Endpunkt haben gibt nichts zurück, und es gibt eine Warnung in der Konsole

warn: Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker[0] 
     Authorization failed for the request at filter 'Microsoft.AspNet.Mvc.Filters.AuthorizeFilter'. 

Ich kann hallo t andere Endpunkte, die das Attribut nicht erfolgreich haben.

SOS, Jack

+0

Gleiches Problem. Hast du das jemals herausgefunden? – rob

+0

Ja und ich antwortete unten, es fällt inline mit Ihrem Kommentar auf adem Kommentar – Hamburglar

Antwort

3

Die Antwort auf diese Frage ist in einem Kommentar zu Adem Caglin angespielt, so Requisiten für ihn.

Das Problem ist, dass die AuthorizeFilter die Anfrage ablehnt, bevor die AuthorizationHandler aufgerufen wird. Dies liegt daran, dass MVC für jede Verwendung des Tags AuthorizeAuthorizeFilter vor dem AuthorizationHandler in der Pipeline hinzufügt. Diese AuthorizeFilter prüft, ob eine der aktuellen Benutzeridentitäten autorisiert ist. In meinem Fall gab es keine autorisierten Identitäten, die mit einem Benutzer verbunden waren, daher würde dies immer fehlschlagen.

Eine Lösung (die IMO ist etwas hackish) ist ein Stück Middleware einzufügen, die vor jedem MVC-Code ausgeführt wird. Diese Middleware fügt einem Benutzer eine generische authentifizierte Identität hinzu (wenn der Benutzer noch keine hat).

Folglich wird die AuthorizeFilter Prüfung bestanden und die Handle Methode auf der AuthenticationHandler Methode wird ausgeführt und unser Problem wird gelöst. Der Middleware-Code (die Configure vor app.UseMvc(); hinzugefügt werden muss genannt wird) ist wie folgt

app.Use(async (context, next) => 
    { 
     if (!context.User.Identities.Any(i => i.IsAuthenticated)) 
     { 
      context.User = new ClaimsPrincipal(new GenericIdentity("Unknown")); 
     } 
     await next.Invoke(); 
    }); 

Eine alternative Möglichkeit, die AuthorizeFilter außer Kraft zu setzen ist hier umreißen (Override global authorize filter in ASP.NET Core MVC 1.0)

die Antwort von hier zitierend (Asp.Net Core policy based authorization ends with 401 Unauthorized)

1

Werfen Sie einen Blick auf Asp.net Core Authorize Redirection Not Happening ich denke, das Hinzufügen options.AutomaticChallenge = true; Ihr Problem löst.

+0

Ich denke, dass das spezifisch für CookieAuthentication sein könnte. Wenn ich 'services.AddAuthorization() 'nenne, bekomme ich eine Instanz von' AuthorizationOptions', die kein 'AutomaticChallenge' Feld hat – rob

+0

welche Authentifizierungs Middleware verwendest du? –

+3

Wenn Sie '[Autorisieren]' Attribut ohne Authentifizierung verwenden, siehe http://stackoverflow.com/questions/37276005/asp-net-core-policy-based-authorization-ends-with-401-unauthorized –

5

Ich stelle das hier als Referenz, weil ich viel zu lange damit verbracht habe, dies herauszufinden ...

ich eine benutzerdefinierte Anforderung und Handler (leer zum Testen willen) umgesetzt hatte:

using Microsoft.AspNetCore.Authorization; 
using System.Threading.Tasks; 

public class TestHandler : AuthorizationHandler<TestRequirement>, IAuthorizationRequirement 
{ 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TestRequirement requirement) 
    { 
     context.Succeed(requirement); 
     return Task.CompletedTask; 
    } 
} 

public class TestRequirement : IAuthorizationRequirement 
{ 

} 

es in meinem Startup.csConfigureServices() Abschnitt Registriert:

services.AddAuthorization(options => 
{ 
    options.AddPolicy("Test", policy => policy.Requirements.Add(new TestRequirement())); 
    // Other policies here 
} 

es zu meiner Controller-Methode:

[HttpGet] 
[Authorize(Policy = "Test")] 
public IActionResult Index() 
{ 
    Return View(); 
} 

Aber bekam ein 403 Fehler (nicht 401) bei jeder Anfrage an die Controller-Methode!

Es stellte sich heraus, dass ich TestHandler mit der ConfigureServices() (Dependency Injection) -Abschnitt von Startup.cs nicht registriert.

services.AddSingleton<IAuthorizationHandler, TestHandler>(); 

Hoffe, dass dies jemand vor dem Kopf auf ihren Schreibtisch hämmern rettet. : |

+1

Es für mich behoben. So sehr ich die Aufnahme von DI in AspNetCore liebe, ist es manchmal verwirrend, was Sie registrieren müssen und wie. – mode777