2017-09-19 19 views
5

Tôi có ứng dụng .NET Core 2.0 sử dụng mã thông báo JWT để ủy quyền cho người dùng. Tất cả đều hoạt động tốt nhưng tôi muốn có một số loại cơ chế API Key để cho phép các ứng dụng khác tích hợp nhưng tôi dường như không thể làm việc này với xác thực hiện tại.. Xác thực JWT lõi Net với khóa API tùy chỉnh 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(); 
      } 
     }); 
    } 
} 

Vì vậy, trong đoạn code trên bạn có thể thấy rằng tôi đang chặn các yêu cầu HTTP cung cấp một tiêu đề gọi ApiKey và sau đó xác nhận nó với những gì tôi đã được lưu trữ. Phần này tất cả các công trình nhưng khi gọi một phương pháp API với Authorize thuộc tính này không làm việc và tôi nhận được các bản ghi lỗi sau:

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 

Bây giờ tôi đoán đây là để làm với yêu cầu chỉ cung cấp một tiêu đề ApiKey và không phải là tiêu đề Authorization với mã thông báo JWT chính xác.

Làm cách nào để chỉ có thể cung cấp tiêu đề ApiKey và khi không có tiêu đề ApiKey, sau đó dự phòng yêu cầu mã thông báo JWT?

+0

Bạn đang sử dụng Asp.net Identity? –

+0

@AramKocharyan Có –

+0

Bạn có sử dụng thuộc tính 'Authorize' với thuộc tính' Roles' không? Giống như '[Authorize (Roles =" foo ")]' –

Trả lời

3

Áp dụng Claim("role", "Admin") đến GenericPrincipal sẽ không ảnh hưởng đến bất kỳ điều gì, bởi vì GenericPrincipal không liên quan gì đến Tuyên bố vai trò. Vì vậy, nếu bạn muốn áp dụng vai trò quản trị cho GenericPrincipal, bạn cần phải thêm vai trò đó vào thông số hàm tạo:

var principal = new GenericPrincipal(identity, new[] {"Admin","ApiUser"}); 
context.User = principal; 
Các vấn đề liên quan