1

I have to add our custom Basic Authentication Handler, but our implementation requires to pass parameter to it. I am not able to achieve this using DI. Here is part of the code:

    // Part of ConfigureServices in Startup.cs
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        ...
        // Some DIs in ConfigureService
        services.AddTransient<ICustomService, CustomService>(); //this should be passed later to handler
        services.AddHttpContextAccessor();
        ...
        // Adding authentication in ConfigureServices
        services.AddAuthentication("Basic")
            .AddScheme<CustomBasicAuthenticationOptions, CustomBasicAuthenticationHandler>(
            "Basic",
            options => new CustomBasicAuthenticationOptions()
            {
                CustomService = ??? // HOW OT GET CustomService: ICustomService from Container here?
            });
      ...
   }

   // CustomBasicAuthenticationOptions
   public class CustomBasicAuthenticationOptions : AuthenticationSchemeOptions
   {
       public CustomBasicAuthenticationOptions();
       public static string AuthenticationScheme { get; }
       public ICustomService CustomService { get; set; }  //THIS SHOULD BE INJECTED HERE during AddAuthentication?! How?
       ...
   }

   // CustomService and its constructor of 
   public class CustomService : ICustomService 
   {
       public CustomService(IHttpContextAccessor httpContextAccessor) {
          ...
       }
   }
0

1 Answer 1

1

You comment in the original example shows what actually depends on the service

// this should be passed later to handler

Move the service over to the handler as an explicit dependency via constructor injection.

public class CustomBasicAuthenticationHandler : AuthenticationHandler<CustomBasicAuthenticationOptions> {
    private readonly ICustomService customService;

    public CustomBasicAuthenticationHandler(
        ICustomService customService, //<-- NOTE
        IOptionsMonitor<BasicAuthenticationOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock
    )
    : base(options, logger, encoder, clock) {
        this.customService = customService;
    }

    //...
}

And refactor the registration

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    //...

    // Some DIs in ConfigureService
    services.AddTransient<ICustomService, CustomService>(); //this should be passed later to handler
    services.AddHttpContextAccessor();

    //...

    // Adding authentication in ConfigureServices
    services.AddAuthentication("Basic")
        .AddScheme<CustomBasicAuthenticationOptions, CustomBasicAuthenticationHandler>("Basic", null);

    //...
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.