wake-up-neo.com

ASP.NET Core 2.0-JWT-Überprüfung schlägt fehl, Fehler bei der Autorisierung für Benutzer: (null) `

Ich verwende ASP.NET Core 2.0-Anwendung (Web-API) als JWT-Aussteller, um ein Token zu generieren, das von einer mobilen App verwendet werden kann. Leider kann dieses Token nicht von einem Controller validiert werden, während es von einem anderen Controller validiert werden kann (mit derselben Validierungseinstellung in derselben asp.net core 2.0-App).

Ich habe also ein Token, das gültig ist und dekodiert werden kann, alle erforderlichen Ansprüche und Zeitstempel hat. Aber ein Endpunkt akzeptiert es, während ein anderer mir 401 Fehler- und Debugausgabe gibt: 

Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Informationen: Die Autorisierung ist für den Benutzer fehlgeschlagen: (null).

[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed for user: (null).
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed for user: (null).
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
      Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes ().
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
      Executing ChallengeResult with authentication schemes ().
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
      AuthenticationScheme: Bearer was challenged.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AuthenticationScheme: Bearer was challenged.
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action MyController.Get (WebApi) in 72.105ms
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action MyController.Get (WebApi) in 72.105ms
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 271.077ms 401 
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 271.077ms 401 

Mein Validierungs-Setup ist unten:

var secretKey = Configuration["Authentication:OAuth:IssuerSigningKey"];
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
var tokenValidationParameters = new TokenValidationParameters
{
   ValidateIssuerSigningKey = true,
   IssuerSigningKey = signingKey,
   ValidateIssuer = true,
   ValidIssuer = Configuration["Authentication:OAuth:Issuer"],
   ValidateAudience = true,
   ValidAudience = Configuration["Authentication:OAuth:Audience"],
   ValidateLifetime = true,
   ClockSkew = TimeSpan.Zero,
};

services.AddAuthentication(options =>
{
   options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
   options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
   options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
    options.RequireHttpsMetadata = false;
    options.TokenValidationParameters = tokenValidationParameters;
});

Diese beiden Endpunkte sind identisch und leben nur in verschiedenen Controllern, die beide mit dem Attribut Authorize gekennzeichnet sind.

Wie ist das möglich?

25
Alexey Strakh

Die Reihenfolge der add-Anweisungen in der configure-Funktion ist wichtig. Stelle sicher das

app.UseAuthentication();

kommt davor 

app.UseMvc();

Könnte das das Problem gewesen sein?

46
Ole Lindstad

In Ihrer startup.cs ConfigureServices-Methode, wenn Sie hinzufügen

services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options => ...

Erläuterung: Wenn Sie [Authorize] auf einem Controller verwenden, ist er standardmäßig an das erste Autorisierungssystem gebunden. 

options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;

Damit setzen Sie Ihre Standardeinstellung für die JWT-Trägerauthentifizierung.

zusätzlich kannst du hinzufügen 

options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

in dieser Zeile wird verhindert, dass 404-Fehler gefunden werden, wenn Identity mit JWTs verwendet wird. Wenn Sie Identität verwenden, versucht das DefaultChallengeScheme, Sie auf eine Anmeldeseite umzuleiten. Wenn dies nicht der Fall ist, wird eine 404 nicht gefunden und nicht die gewünschte 401 nicht autorisiert. Durch das Setzen des DefaultChallengeScheme auf JwtBearerDefaults.AuthenticationScheme auf Unautorisiertes wird nicht mehr versucht, Sie auf eine Anmeldeseite umzuleiten

Wenn Sie die Cookie-Authentifizierung mit JWT-Authentifizierung im Tag [Authorize] verwenden, können Sie das gewünschte Authentifizierungsschema angeben. zum Beispiel

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
8
Kevin

Ich fügte hinzu:

app.UseAuthentication();

In Startup.Configure() und das hat diesen Fehler für mich behoben.

Referenz: Auth 2.0 Migrationsankündigung

3
spottedmahn

versuchen Sie dies in startup.cs

services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(opts => ...
2
user1508188

Wenn Authentifizierungen hinzugefügt werden, wie:

  services.AddAuthentication(options => {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        ....

Dies bedeutet, dass jedes Attribut [Authorize], das auf einer Methode oder einer Controllerklasse abgelegt wird, versucht, sich beim Standardauthentifizierungsschema (in diesem Fall dem JwtBearer) und es wird kein CASCADE DOWN authentifiziert Versuchen Sie, sich mit anderen Schemas zu authentifizieren, die möglicherweise deklariert wurden (z. B. Cookie-Schema). Damit sich AuthorizeAttribute gegenüber dem Cookie-Schema authentifizieren kann, muss es wie angegeben angegeben werden 

[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]

Dies funktioniert auch in umgekehrter Reihenfolge. Wenn das Cookie-Schema standardmäßig verwendet wird, muss das JwtBearer-Schema für die Autorisierung der Methoden oder Controller deklariert werden, für die die JwtBearer-Token-Authentifizierung erforderlich ist

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
0
theCuriousOne

Überprüfen Sie die Codierung des Signaturschlüssels in Ihrem Token-Provider. Es kann beispielsweise UTF8 und nicht ASCII sein.

0
H.Wojtowicz

Dies scheint das Verhalten zu sein, das Sie erhalten, wenn Ihre JWT nicht korrekt überprüft wurde. Ich hatte dieses Problem als Ergebnis der Eingabe von "Bearer: (JWT)" anstelle von "Bearer (JWT)" in der Kopfzeile

0
Jon B