DelegateHandler в RequestDelegate migrate и сервисы для регистрации при запуске - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь перенести проверку подлинности 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();
        });
    }
}
...