Rupesh K

Rupesh K

  • NA
  • 158
  • 1.6k

DelegateHandler to RequestDelegate migrate asp.net core 3.1

May 6 2020 9:46 AM
I am trying to migrate the DelegateHandler apikey authentication to RequestDelegate apikey authentication.I was able to create below code ,but need clarification wheather the code configuration is correct and how to return error code if any condition fails in "async Task Invoke" method of DelegatingHandler class.
 
Using RequestDelegate:
  1. public class DelegatingHandler {  
  2.  private readonly RequestDelegate _next;  
  3.  private readonly ILogger _logger;  
  4.  private ISecurityService _securityService;  
  5.  public DelegatingHandler(RequestDelegate next, ILogger logger, ISecurityService securityService) {  
  6.   _next = next;  
  7.   _logger = logger;  
  8.   _securityService = securityService;  
  9.  }  
  10.   
  11.  public async Task Invoke(HttpContext context, HttpRequestMessage request) {  
  12.   try {  
  13.    //Get API Key         
  14.    string apiKey = request.ApiKey();  
  15.   
  16.    //Check for APIKEY in header  and if null retun error code with message  
  17.    if (apiKey == null || apiKey.Trim().Equals(string.Empty)) {  
  18.     //Not sure this is correct,Please correct what to be added to return error status  
  19.     new HttpResponseMessage(HttpStatusCode.Unauthorized) {  
  20.      Content = new StringContent("Header information for ApiKey is missin")  
  21.     };  
  22.    }  
  23.    string message = "";  
  24.    //Splitting the UserName and Key, the format will he username:key  
  25.    string[] identity = apiKey.Split(':');  
  26.    if (!IsAuthorized(identity, request.RequestUri.AbsolutePath.ToString(), request.Method.ToString(),  
  27.      ref message)) {  
  28.   
  29.     //Not sure this is correct,Please correct what code to be added to return error status  
  30.     new HttpResponseMessage(HttpStatusCode.Unauthorized) {  
  31.      Content = new StringContent("Header information for ApiKey is missin")  
  32.     };  
  33.    } else {  
  34.     //Setting the identity  
  35.     IPrincipal principal = new GenericPrincipal(  
  36.      new GenericIdentity(identity[0]), null);  
  37.     Thread.CurrentPrincipal = principal;  
  38.   
  39.     _logger.Info(message,  
  40.      new {  
  41.       EndPoint = request.RequestUri.AbsolutePath.ToString(),  
  42.        UserName = Thread.CurrentPrincipal.Identity.Name  
  43.      });  
  44.    }  
  45.    await _next.Invoke(context);  
  46.   } catch (Exception ex) {  
  47.    //Not sure this is correct,Please correct what code to be added to return error status  
  48.    new HttpResponseMessage(HttpStatusCode.InternalServerError) {  
  49.     Content = new StringContent(ex.ToString())  
  50.    };  
  51.   }  
  52.  }  
  53.   
  54.  private bool IsAuthorized(string[] identity, string requestAbsolutePath, string httpMethod, ref string message) {  
  55.   try {  
  56.    //Make a DB call and check from _securityService call ,DO we need to register them in Startup class  
  57.   
  58.    message = "Unauthorized to access the requested resource";  
  59.   } catch (Exception ex) {  
  60.    message = ex.Message;  
  61.    _logger.Error("VSphereDelegationHandler Failed"new {  
  62.     Method = "IsAuthorized"  
  63.    }, ex);  
  64.   }  
  65.   
  66.   return false;  
  67.  }  
  68. }  
APIKey Extension:
  1. public static class ApiKeyExtensions {  
  2.  public static IApplicationBuilder UseApiKey(this IApplicationBuilder builder) {  
  3.   return builder.UseMiddleware < VSphereDelegatingHandler > ();  
  4.  }  
  5. }  
In the startup.cs class do we need to register all the service Interface and Class files ,but I am getting error in program.cs
 
Program.cs
  1. public class Program {  
  2.  public static void Main(string[] args) {  
  3.   CreateHostBuilder(args).Build().Run();  
  4.  }  
  5.   
  6.  public static IHostBuilder CreateHostBuilder(string[] args) =>  
  7.   Host.CreateDefaultBuilder(args)  
  8.   .ConfigureWebHostDefaults(webBuilder => {  
  9.    webBuilder.UseStartup < Startup > ();  
  10.   });  
  11. }  
StartUp.cs
  1. public class Startup  
  2. {  
  3.     public Startup(IConfiguration configuration)  
  4.     {  
  5.         Configuration = configuration;  
  6.     }  
  7.     public IConfiguration Configuration { get; }  
  8.    
  9.     // This method gets called by the runtime. Use this method to add services to the container.  
  10.     public void ConfigureServices(IServiceCollection services, string dbConnectionString)  
  11.     {  
  12.         services.AddControllers();  
  13.    
  14.          services.AddScoped<ISecurityService, SecurityService>();  
  15.          services.AddScoped<ISecurityDataService, SecurityDataService>();  
  16.          services.AddScoped<ISecurityCheckService, SecurityCheckService>();  
  17.         //Additional service are registered and is the below DB register is correct  
  18.         services.AddScoped<IDBOps, DBOps>(db => new DBOps(dbConnectionString));  
  19.     }  
  20.    
  21.     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.  
  22.     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
  23.     {  
  24.         if (env.IsDevelopment())  
  25.         {  
  26.             app.UseDeveloperExceptionPage();  
  27.         }  
  28.    
  29.         app.UseRouting();  
  30.    
  31.         app.UseAuthorization();  
  32.    
  33.         app.UseApiKey();  
  34.    
  35.         app.UseEndpoints(endpoints =>  
  36.         {  
  37.             endpoints.MapControllers();  
  38.         });  
  39.     }  
  40. }