2017-02-05 3 views
2

Wenn ClaimsIdentity durch JwtBearerAuthentication Middleware gesetzt leider nicht genug Rollen, um durchJwtBearerAuthentication tut 403 Forbidden zurückkehren, kehrt immer 401 Unauthorized

[Authorize(Roles="whateverrole")] 

es 401 gibt statt 403.

ich mit diesem in asp habe Schwierigkeiten .net Core Web API die ganze Nacht. Ich habe auch diese Frage auf stackoverflow gesehen, aber ich habe keine Lösung gesehen, die ich Arbeit machen könnte. Die Reihenfolge der Registrierung von Middleware und der Einstellung von AutomaticChallange hat die Aufgabe erfüllt.

Ich weiß nicht, ob ich etwas vermisse, aber es scheint schockierend, dass dies seit Jahren nicht richtig gelöst wurde. Es ist so nervig.

Gibt es eine normale, normale, non-workaround, non-hack Möglichkeit, dies zu lösen?

UPDATE (in Antwort von @juunas Kommentar)

habe ich versucht, dass Rollen und richtig aus Ansprüchen kartiert. Wenn ich also die Rollenanforderung aus dem Attribut lösche, gibt User.IsInRole (x) für alle Rollen, denen dieser Benutzer zugewiesen ist (im JWT-Token), true zurück. Das Mapping funktioniert also gut.

Über das Verschieben von rollenbasierter Autorisierung zu Richtlinien ... können Sie einige Links zu Best Practices, Empfehlungen oder etwas, auf dem Sie diese Aussage aufbauen, bereitstellen? Ich sage nicht, dass es nicht etwas zu tun ist, aber ich möchte es einfach verstehen.

+0

Haben Sie versucht, die Rollenanforderung zu entfernen und zu sehen, ob 'User.IsInRole (" whateverrole ")' true zurückgibt? In ASP.NET Core sollten Sie versuchen, sich von der rollenbasierten Autorisierung zu entfernen, da Sie in der Middleware definieren müssen, welchen Anspruch sie als Rollen berücksichtigen soll. Es ist einfacher, eine Richtlinie zu erstellen, die das Vorhandensein dieses Anspruchs erfordert, und den Richtliniennamen für AuthorizeAttribute anzugeben. – juunas

+0

Danke für Ihren Kommentar. Ich habe darauf in Frage UPDATE geantwortet. –

+0

Nun, die offizielle ASP.NET Core-Dokumentation ist ziemlich gut für das Verständnis, wie die Autorisierung erfolgen kann: https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims – juunas

Antwort

0

Es ist wichtig, den Unterschied zu Fehlern zu verstehen, um zu verstehen, warum Sie das eine und nicht das andere bekommen.

401 ist für die Authentifizierung. Wenn Sie diesen Fehler erhalten, müssen Sie sich fragen, ob der Benutzer angemeldet ist, oder hat der Benutzer ein aktuelles Token, das von einem gültigen Token-Provider bereitgestellt wird? Wenn das Token abgelaufen ist oder der Provider nicht gültig ist, können Sie eine 401 erhalten. Wenn dies der Fall ist, müssen Sie User.Identity.IsAuthenticated überprüfen. Am wahrscheinlichsten gibt es falsch zurück.

403 ist für die Autorisierung. Dies würde bedeuten, dass der Benutzer ein gültiges Token besitzt, aber das Token, über das er verfügt, gewährt ihm keinen Zugriff auf die angeforderte Ressource. Hier sollten Sie User.IsInRole() überprüfen und es würde false zurückgeben.

Wenn Sie 401 erhalten, bedeutet dies, dass der Benutzer nicht authentifiziert wurde, dh er ist nicht eingeloggt, sein Login war ungültig, das Token ist abgelaufen ... usw. Was Ihre Anwendung betrifft, ist der Benutzer hat nicht bewiesen, dass sie es sind, von denen sie sagen, dass sie es schon sind.

Bearbeiten: Entschuldigung für die Annahme, der Benutzer wurde nicht Authenticated, ich habe nicht gesehen, wo Sie angegeben, dass sie in Ihrem ersten Beitrag waren. Es ist schwer zu helfen, ohne Code zu sehen, aber meine nächste Vermutung ist, dass die Claims-Prüfung nicht zur Service-Pipeline hinzugefügt wurde.

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddMvc(); 

    services.AddAuthorization(options => 
    { 
    options.AddPolicy("whateverrole", policy => policy.RequireClaim("whateverrole")); 
    }); 
} 

Dies ist in Ihrem Startup.cs. MS-Dokument ist hier https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims

Letztes Update: Einfach mit dem Standard-Attribut Autorisieren Attribute können Sie es nicht ändern. MS entwirft diesen Weg aufgrund der Anzahl der Schichten in der Pipeline, die sich auf die Authentifizierung auswirken könnten. Ich war mir dessen nicht bewusst, weil ich ein benutzerdefiniertes Autorize-Attribut verwende und vergessen habe, dass ich die Art und Weise, wie Statuscodes behandelt wurden, überschrieb.

Allerdings fand ich eine schöne Lösung, die Ihren Bedürfnissen https://github.com/aspnet/Security/issues/872#issuecomment-232624106 Hotel könnte

Es eine Fehlerseite an die Pipeline vor der app.UseMvc fügt hinzu(), die Authentifizierungsfehler auf eine Fehlerseite umleitet, die den korrekten Statuscode zurückgibt .

+0

i Ich möchte hier nur erklären: Das ist genau das Problem, dass der Benutzer IsAuthenticated = true ist, aber da der Benutzer nicht genügend Rollen hat, kann er die Autorisierung nicht weitergeben. Also sollte seine 403 zurückgegeben werden nicht, seine 401, die zurückgegeben wird. Und das ist offensichtlich falsch. –

+0

ok, das ist auch ein gutes Beispiel. Haben Sie diesen Code ausprobiert? Ich habe auch Richtlinien getestet und es gibt immer noch 401 anstelle von 403. Was kommt auf Ihrer Seite zurück Wenn der Benutzer nicht "whereverrole" Anspruch haben? –

+0

ja, aber es gibt Empfehlungen von asp.net Core Security-Team nicht benutzerdefinierte Autorize-Attribute verwenden. Auch eine Fehlerseite ist keine Option für Web-API, zum Beispiel. Ich könnte vermisst werden etwas wichtiges, aber soweit ich das beurteilen kann, kann ich einfach nicht glauben, dass diese Verwirrung passiert. und es passiert seit Jahren. es ist sein Kerngeschäft. –