2017-08-21 31 views
5

Tôi đang phát triển một ứng dụng mà người dùng có thể xác thực thông qua tên người dùng và mật khẩu và chúng tôi cung cấp mã thông báo JWT sau đó được xác thực trên máy chủ.. Net Core Web Api Key

Một điều tôi muốn thêm là khả năng có một Khóa API đặc biệt (guid) mà người dùng có thể sử dụng khi tích hợp với ứng dụng này thay vì sử dụng tên người dùng và mật khẩu.

Tôi không chắc chắn cách thực hiện việc này vì phần xác thực có vẻ hơi giống hộp đen (sử dụng Nhận dạng Aspnet).

Dưới đây là một số mã của tôi cho các thiết lập xác thực

Startup.cs

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add framework services. 
    services.AddDbContext<OmbiContext>(options => 
     options.UseSqlite("Data Source=Ombi.db")); 

    services.AddIdentity<OmbiUser, IdentityRole>() 
     .AddEntityFrameworkStores<OmbiContext>() 
     .AddDefaultTokenProviders(); 

    services.Configure<IdentityOptions>(options => 
    { 
     options.Password.RequireDigit = false; 
     options.Password.RequiredLength = 1; 
     options.Password.RequireLowercase = false; 
     options.Password.RequireNonAlphanumeric = false; 
     options.Password.RequireUppercase = false; 
    }); 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMemoryCache cache) 
{ 
    var tokenOptions = (IOptions<TokenAuthentication>)app.ApplicationServices.GetService(
     typeof(IOptions<TokenAuthentication>)); 

    var ctx = (IOmbiContext)app.ApplicationServices.GetService(typeof(IOmbiContext)); 

    var tokenValidationParameters = new TokenValidationParameters 
    { 

     ValidateIssuerSigningKey = true, 
     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.Value.SecretKey)), 

     RequireExpirationTime = true, 
     ValidateLifetime = true, 
     ValidAudience = "Ombi", 
     ValidIssuer = "Ombi", 
     ClockSkew = TimeSpan.Zero 
    }; 

    app.UseJwtBearerAuthentication(new JwtBearerOptions() 
    { 
     Audience = "Ombi", 
     AutomaticAuthenticate = true, 
     TokenValidationParameters = tokenValidationParameters, 

    }); 
//.... 
} 

Đoạn mã trên hoạt động khi có [Authorized] thuộc tính trên bộ điều khiển và kiểm tra đối với vai trò và như vậy.

Bất kỳ ai cũng có ý tưởng làm cách nào để chuyển một số loại tiêu đề Api-Key cho tất cả các yêu cầu chứa Khóa API đặc biệt này để chuyển các thuộc tính [Authorized]? (Phím được lưu trữ trong Db)

Cảm ơn

+0

https://stackoverflow.com/questions/31464359/how-do-you -create-a-custom-authorizeattribute-in-asp-net-core – stuartd

+0

@stuartd Không chắc chắn nếu các điều trên áp dụng, nhìn vào nó tôi sẽ cần phải xác định chính sách đó cho mọi bộ điều khiển, trong trường hợp đó tiêu đề API Key sẽ sau đó luôn cần phải có mặt. Về cơ bản tôi đang tìm kiếm một cách để cung cấp một bí mật cho máy chủ cho phép tôi. –

+0

Bạn cung cấp mã thông báo mang với tiêu đề Cấp quyền theo yêu cầu. Và tùy thuộc vào máy chủ ủy quyền có vị trí bạn cần phải xác nhận nó. I E. Trong azure AD bạn thêm một api dưới appregistration nếu bạn chỉ muốn xác nhận hợp lệ đối với một khóa hardcoded trong máy chủ bạn có thể xác nhận bởi bạn sở hữu xác nhận xác nhận quyền sở hữu, hãy kiểm tra lớp AuthorizationHandler – joakimja

Trả lời

0

Đây là những gì tôi đã làm cuối cùng:

public static void ApiKeyMiddlewear(this 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(); 
        await ValidateApiKey(serviceProvider, context, next, headerKey); 
       } 
       else if (context.Request.Query.ContainsKey("apikey")) 
       { 
        if (context.Request.Query.TryGetValue("apikey", out var queryKey)) 
        { 
         await ValidateApiKey(serviceProvider, context, next, queryKey); 
        } 
       } 
       else 
       { 
        await next(); 
       } 
      } 
      else 
      { 
       await next(); 
      } 
     }); 
    } 

    private static async Task ValidateApiKey(IServiceProvider serviceProvider, HttpContext context, Func<Task> next, string key) 
    { 
     // validate it here 
     var valid = false; 
     if (!valid) 
     { 
      context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 
      await context.Response.WriteAsync("Invalid API Key"); 
     } 
     else 
     { 
      var identity = new GenericIdentity("API"); 
      var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" }); 
      context.User = principal; 
      await next(); 
     } 
    }