The*_*eek 4 entity-framework-6 asp.net-web-api2 asp.net-core
ASP.Net Core noob here ...我正在使用DNX的Net.Net核心WebAPI核心项目.
我需要在我们的服务中实现API Key auth.为此,我创建了中间件,从请求中获取信息并继续进行身份验证.支持转到数据库,获取匹配的密钥,然后返回并进行验证.
这是为了查看上下文并获取APIKey而实现的中间件
的AuthenticationHandler
public class AuthorizationHandler
{
private readonly RequestDelegate _next;
private IAuthenticationService _authenticationService;
public AuthorizationHandler(RequestDelegate next, IAuthenticationService authService)
{
_authenticationService = authService;
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
var apiKey = context.Request.Headers["Key"];
var location = context.Request.Headers["Host"];
var locationKey = _authenticationService.GetApiKey(location);
if (apiKey == locationKey)
await _next(context);
context.Response.StatusCode = 403;
context.Response.Headers.Add("WWW-Authenticate",
new[] { "Basic" });
}
catch (Exception ex)
{
context.Response.StatusCode = 500;
context.Response.Headers.Add("WWW-Authenticate",
new[] { "Basic" });
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是具有上下文和中间件注册的启动类
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfiguration Configuration { get; set; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped(k => new DbContext(Configuration["Data:Context:ConnectionString"]));
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseIISPlatformHandler();
app.UseStaticFiles();
app.RegisterAuthorizationHeader();
app.RegisterAuthorization();
app.UseMvc();
}
// Entry point for the application.
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
Run Code Online (Sandbox Code Playgroud)
这是Auth服务
public interface IAuthenticationService
{
string GetApiKey(string location);
}
public class AuthenticationService: IAuthenticationService
{
private IApiKeyRepository _apiKeyRepository;
public AuthenticationService(IApiKeyRepository repo)
{
_apiKeyRepository= repo;
}
public string GetApiKey(string location)
{
return _apiKeyRepository.GetApiKeyByLocation(location);
}
}
Run Code Online (Sandbox Code Playgroud)
回购
public interface IApiRepository
{
string GetApiKeyByLocation(string location);
}
public class ApiRepository: IApiRepository
{
private DbContext _context;
public ApiRepository(DbContext context)
{
_context = context;
}
public string GetApiKeyByLocation(string location)
{
var apiRow = _context.ApiKeyStore.FirstOrDefault(a => a.Location == location);
return apiRow == null ? string.Empty : apiRow.APIKey;
}
}
Run Code Online (Sandbox Code Playgroud)
尝试此操作时,我收到以下错误:
在创建模型时不能使用上下文.如果在OnModelCreating方法中使用上下文,或者同时由多个线程访问相同的上下文实例,则可能抛出此异常.请注意,DbContext和相关类的实例成员不保证是线程安全的.
现在,当我调试这个时,每个断点都被击中两次.我相信我理解为什么这个问题正在发生,但不知道如何解决它.
有人可以给我一个想法吗?有更好的解决方案吗?
要在中间件(根据定义必须是单例)中使用范围依赖关系,最好的方法是将其作为参数传递InvokeAsync而不是通过构造函数流动它:
public async Task Invoke(HttpContext context, IAuthenticationService authenticationService)
{
try
{
var apiKey = context.Request.Headers["Key"];
var location = context.Request.Headers["Host"];
var locationKey = authenticationService.GetApiKey(location);
if (apiKey == locationKey)
await _next(context);
context.Response.StatusCode = 403;
context.Response.Headers.Add("WWW-Authenticate",
new[] { "Basic" });
}
catch (Exception ex)
{
context.Response.StatusCode = 500;
context.Response.Headers.Add("WWW-Authenticate",
new[] { "Basic" });
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1157 次 |
| 最近记录: |