C# Dependency Injection - Authentication

Viewed 1009

I am trying to figure out .net core dependency injection. My project is currently a web api, with some custom authentication. I've added my authentication like so (in Startups.cs under "ConfigureServices":

services.AddAuthentication(Authentication.Hmac.HmacDefaults.AuthenticationScheme).AddHmac(options =>
                {
                    options.AuthName = "myname";
                    options.CipherStrength = HmacCipherStrength.Hmac256;
                    options.EnableNonce = true;
                    options.RequestTimeLimit = 5;
                    options.PrivateKey = "myprivatekey";
                });

My question is this: How do you access IMemoryCache within the authentication service? I've tried just created a new MemoryCache and passing it in, but that doesn't work. The main goal is for checking Nonce values (see if they are in the cache, if yes auth fails, if no, add to cache auth passes).

Again, this is .NET Core 2 (Web API).

UPDATES:

Here is the basis of the HmacHandler class (the part that ACTUALLY does the auth):

public class HmacHandler : AuthenticationHandler<HmacOptions>
{
private static string Signature;
private static string Nonce;
private static Encoding Encoder { get { return Encoding.UTF8; } set { } }

IMemoryCache MemoryCache { get; set; }

public HmacHandler(IOptionsMonitor<HmacOptions> options, ILoggerFactory logger, UrlEncoder encoder, IDataProtectionProvider dataProtection, ISystemClock clock)
: base(options, logger, encoder, clock)
{
}

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{...}
}

Then there is the "Options" class.

public class HmacOptions : AuthenticationSchemeOptions
{...}

It can't have a constructor that takes parameters. I need to USE the IMemoryCache in the HmacHandler class. I tried adding IMemoryCache to it (in the constructor, etc). That did NOT work.

4 Answers

You would need to set IMemoryCache MemoryCache { get; set; } to public if you would like to use outside of the class via dependency injection.

public IMemoryCache MemoryCache { get; set; }

So the answer ended up being a combination of things here. So here is what I did:

  1. Add the "public" to the IMemoryCache in the HmacHandler
  2. Added the IMemoryCache to the constructor of HmacHandler
  3. Changed the get/set of the cache from "TryGetValue/CreateEntry" to pure "Get/Set".
    private IMemoryCache memoryCache { get; set; }

    public HmacAuthenticationHandler(IOptionsMonitor<HmacAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IMemoryCache memCache)
        : base(options, logger, encoder, clock)
    {
        memoryCache = memCache;
    }

And then in HandleAuthenticateAsync use Get and Set of memoryCache.

    public void ConfigureServices(IServiceCollection services)
    {                        

        services.AddMemoryCache();
services.AddAuthentication(Authentication.Hmac.HmacDefaults.AuthenticationScheme).AddHmac(options =>
                {
                    options.AuthName = "myname";
                    options.CipherStrength = HmacCipherStrength.Hmac256;
                    options.EnableNonce = true;
                    options.RequestTimeLimit = 5;
                    options.PrivateKey = "myprivatekey";
                    // do your stuff with Test class here
                });

    }
public class Test {
  private IMemoryCache _cache;
  public Test(IMemoryCache cache) {
    _cache = cache;
  }
}
Related