2017-09-19 5 views
5

Ich habe eine .NET Core 2.0-Anwendung, die JWT-Tokens verwendet, um den Benutzer zu autorisieren. Das alles funktioniert gut, aber ich möchte eine Art von API-Key-Mechanismus haben, um andere Anwendungen zu integrieren, aber ich kann nicht scheinen, dass dies mit der aktuellen Authentifizierung funktioniert..Net Core JWT-Authentifizierung mit benutzerdefinierten API-Schlüssel Middleware

Code:

Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, 
      IMemoryCache cache, IServiceProvider serviceProvider) 
{ 
    app.UseAuthentication(); 

    ApiKeyMiddlewear(app, serviceProvider); 

    app.UseMvc(routes => 
    { 
     routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 

      routes.MapSpaFallbackRoute(
       name: "spa-fallback", 
       defaults: new { controller = "Home", action = "Index" }); 
     }); 
    } 
} 


    private static void ApiKeyMiddlewear(IApplicationBuilder app, IServiceProvider serviceProvider) 
    { 
     app.Use(async (context, next) => 
     { 
      if (context.Request.Path.StartsWithSegments(new PathString("/api"))) 
      { 
       // Let's check if this is an API Call 
       if (context.Request.Headers["ApiKey"].Any()) 
       { 
        // validate the supplied API key 
        // Validate it 
        var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault(); 
        var settingsProvider = serviceProvider.GetService<ISettingsService<OmbiSettings>>(); 
        var ombiSettings = settingsProvider.GetSettings(); 
        var valid = ombiSettings.ApiKey.Equals(headerKey, StringComparison.CurrentCultureIgnoreCase); 
        if (!valid) 
        { 
         context.Response.StatusCode = (int) HttpStatusCode.Unauthorized; 
         await context.Response.WriteAsync("Invalid API Key"); 
        } 
        else 
        { 
         var identity = new GenericIdentity("API"); 
         identity.AddClaim(new System.Security.Claims.Claim("Origin", "Api")); 
         identity.AddClaim(new System.Security.Claims.Claim("role", "Admin")); 

         var principal = new GenericPrincipal(identity, new[] {"ApiUser"}); 
         context.User = principal; 
         await next(); 
        } 
       } 
       else 
       { 
        await next(); 
       } 
      } 
      else 
      { 
       await next(); 
      } 
     }); 
    } 
} 

So in dem obigen Code Sie sehen können, dass ich die HTTP-Anforderungen am abfängt, die einen Header namens apikey liefern und validieren es dann zu dem, was ich habe gespeichert. Dieser Teil alles funktioniert aber beim Aufruf einer API-Methode mit dem Authorize führen dies nicht funktioniert und ich bekomme folgende Fehlerprotokolle:

2017-09-19 08:15:17.280 +01:00 [Information] Request starting HTTP/1.1 POST http://localhost:52038/api/v1/Identity/ application/json 372 
2017-09-19 08:15:21.967 +01:00 [Information] Authorization failed for user: "API". 
2017-09-19 08:15:21.976 +01:00 [Information] Authorization failed for the request at filter '"Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter"'. 
2017-09-19 08:15:21.981 +01:00 [Information] Executing ForbidResult with authentication schemes ([]). 
2017-09-19 08:15:21.991 +01:00 [Information] AuthenticationScheme: "Bearer" was forbidden. 
2017-09-19 08:15:21.996 +01:00 [Information] Executed action "Ombi.Controllers.IdentityController.CreateUser (Ombi)" in 38.8268ms 
2017-09-19 08:15:22.004 +01:00 [Information] Request finished in 4723.032ms 403 

Jetzt bin zu raten ich dies mit der Anforderung einen ApiKey Header nur zu tun Versorgung und kein Authorization Header mit einem korrekten JWT Token.

Wie kann ich nur einen ApiKey-Header liefern und wenn es keinen ApiKey-Header gibt, dann muss man auf ein JWT-Token zurückgreifen?

+0

Verwenden Sie Asp.net Identität? –

+0

@AramKocharyan Ja –

+0

Verwenden Sie das 'Authorize' Attribut mit' Roles' Eigenschaft? Like '[Authorize (Roles =" foo ")]' –

Antwort

3

Das Anwenden von Claim("role", "Admin") auf GenericPrincipal beeinflusst nichts, weil GenericPrincipal nichts mit Rollenansprüchen zu tun hat. Also, wenn Sie Admin-Rolle zu GenericPrincipal anwenden möchten, müssen Sie es in Konstruktor Parameter hinzuzufügen:

var principal = new GenericPrincipal(identity, new[] {"Admin","ApiUser"}); 
context.User = principal; 
Verwandte Themen