2017-08-21 101 views
5

我正在开发一个应用程序,用户可以通过用户名和密码进行身份验证,然后我们提供一个JWT令牌,然后在服务器上进行验证。.Net Core Web Api密钥

我想添加的一件事是能够拥有一个特殊的API密钥(guid),用户可以在与此应用程序集成时使用,而不是使用用户名和密码。

我不确定如何做到这一点,因为身份验证部分似乎是一个黑盒子(使用Aspnet身份)。

下面是我的一些代码,认证设置有控制器上的[Authorized]属性和检查的作用,并使得当

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, 

    }); 
//.... 
} 

上面的代码工作。

任何人有任何想法如何我可以通过某种含有这种特殊的API密钥为它传递[Authorized]属性的所有请求Api-Key头的? (密钥存储在数据库中)

感谢

+0

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

+0

@stuartd不知道是否上述适用,看着它我需要为每个控制器定义该策略,在这种情况下API Key标题将会总是需要在场。基本上我正在寻找一种方法来向授权我的服务器提供一个秘密。 –

+0

您在请求中提供带授权标头的不记名令牌。根据授权服务器的位置,您需要验证它。即在Azure AD中,如果您只想在服务器上验证硬编码密钥,您可以通过自己的声明验证程序进行验证,然后检查AuthorizationHandler类,然后在appregistration中添加api – joakimja

回答

0

这是我最后还是没买:

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(); 
     } 
    }