Luke1988
Luke1988

Reputation: 2098

ASP.NET Core AuthenticationHandler dependency injection

Following this article, I am trying to implement a custom AuthenticationHandler, but I got stuck on dependency injection.

I need to inject an IRepository instance into the AuthenticationHandler to provide a dbo connection (to check the credentials).

Code:

public class CustomAuthenticationHandler : AuthenticationHandler<CustomAuthenticationOptions>  
{
    // how to inject this?!
    private IRepository repository;

    public CustomAuthenticationHandler(IOptionsMonitor<CustomAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
        : base(options, logger, encoder, clock) {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // this is just a sample
        if (repository.users.Count(w => w.user_name == Request.Headers["user_name"] && w.password == Request.Headers["password"]) == 1) 
        { 
            return Task.FromResult(
                AuthenticateResult.Success(
                    new AuthenticationTicket(
                        new ClaimsPrincipal(Options.Identity),
                        new AuthenticationProperties(),
                        this.Scheme.Name)));
        }

        return Task.FromResult(
            AuthenticateResult.Failed("...");
        );
    }

Do you have any hints?

Thanks

Upvotes: 7

Views: 5458

Answers (2)

pedrommuller
pedrommuller

Reputation: 16056

Just add the repository dependency to the constructor, set the variable in the constructor body

public CustomAuthenticationHandler(
    IOptionsMonitor<CustomAuthenticationOptions> options,
    ILoggerFactory logger,
    UrlEncoder encoder,
    ISystemClock clock,
    IRepository repo)
        : base(options, logger, encoder, clock) {
    repository = repo;
}

Upvotes: 9

Luke1988
Luke1988

Reputation: 2098

Thanks. I tried Jack's solution and it works.

I have had a huge issue with dependency injection of Repository (with EF DataContext) into Middleware. When my Angular SPA loaded, it fired multiple parallel requests into API. I got randomly InvalidOperationExceptions, something like "db context cannot be used while being created"

Absolutely nothing has helped until I totally hopeless moved dependency injection from Middleware constructor into Invoke method:

 public async Task Invoke(HttpContext context, IRepository repository)
 {
     ...

But AuthenticationHandler seems to have a different flow. Works like a charm.

Upvotes: -1

Related Questions