Я пытаюсь перенести проверку подлинности apikey DelegateHandler на проверку подлинности apikey RequestDelegate. Мне удалось создать приведенный ниже код, но мне нужно уточнить, верна ли конфигурация кода и как вернуть код ошибки, если какое-либо условие не выполняется в «asyn c Task Invoke »класса DelegatingHandler.
Использование RequestDelegate:
public class DelegatingHandler
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
private ISecurityService _securityService;
public DelegatingHandler(RequestDelegate next, ILogger logger,ISecurityService securityService)
{
_next = next;
_logger = logger;
_securityService = securityService;
}
public async Task Invoke(HttpContext context, HttpRequestMessage request)
{
try
{
//Get API Key
string apiKey = request.ApiKey();
//Check for APIKEY in header and if null retun error code with message
if (apiKey == null || apiKey.Trim().Equals(string.Empty))
{
//Not sure this is correct,Please correct what to be added to return error status
new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent("Header information for ApiKey is missin")
};
}
string message = "";
//Splitting the UserName and Key, the format will he username:key
string[] identity = apiKey.Split(':');
if (!IsAuthorized(identity, request.RequestUri.AbsolutePath.ToString(), request.Method.ToString(),
ref message))
{
//Not sure this is correct,Please correct what code to be added to return error status
new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent("Header information for ApiKey is missin")
};
}
else
{
//Setting the identity
IPrincipal principal = new GenericPrincipal(
new GenericIdentity(identity[0]), null);
Thread.CurrentPrincipal = principal;
_logger.Info(message,
new
{
EndPoint = request.RequestUri.AbsolutePath.ToString(),
UserName = Thread.CurrentPrincipal.Identity.Name
});
}
await _next.Invoke(context);
}
catch (Exception ex)
{
//Not sure this is correct,Please correct what code to be added to return error status
new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(ex.ToString())
};
}
}
private bool IsAuthorized(string[] identity, string requestAbsolutePath, string httpMethod, ref string message)
{
try
{
//Make a DB call and check from _securityService call ,DO we need to register them in Startup class
message = "Unauthorized to access the requested resource";
}
catch (Exception ex)
{
message = ex.Message;
_logger.Error("VSphereDelegationHandler Failed", new { Method = "IsAuthorized" }, ex);
}
return false;
}
}
Расширение APIKey:
public static class ApiKeyExtensions
{
public static IApplicationBuilder UseApiKey(this IApplicationBuilder builder)
{
return builder.UseMiddleware<VSphereDelegatingHandler>();
}
}
В классе startup.cs нам нужно зарегистрировать все файлы интерфейса и классов службы, но я получаю сообщение об ошибке в program.cs
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
StartUp.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services, string dbConnectionString)
{
services.AddControllers();
services.AddScoped<ISecurityService, SecurityService>();
services.AddScoped<ISecurityDataService, SecurityDataService>();
services.AddScoped<ISecurityCheckService, SecurityCheckService>();
//Additional service are registered and is the below DB register is correct
services.AddScoped<IDBOps, DBOps>(db => new DBOps(dbConnectionString));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseApiKey();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}