Reputation: 817
Is there a way to use Dependency Injection to configure the cookie authentication options? I would like to get some of the settings from the database, but I don't have access to the DatabaseContext at this point.
public void ConfigureServices(IServiceCollection services)
{
...
services
.AddAuthentication(Authentication.scheme)
.AddCookie(Authentication.scheme, options =>
{
options.ExpireTimeSpan = new TimeSpan(30, 0, 0, 0, 0);
options.Cookie.IsEssential = true;
options.Cookie.Name = ".AUTH-Cookie";
options.ReturnUrlParameter = "returnUrl";
options.LoginPath = "/Security/SignIn";
options.LogoutPath = "/Security/SignOut";
options.EventsType = typeof(CookieAuthenticationEvents);
});
...
}
I'm able to use AddOptions() and Configure() to do this with other items in ConfigureServices, but I can't figure out how to do it with the CookieAuthenticationOptions...
services
.AddOptions<MvcOptions>()
.Configure<IDisplayMetadataProvider>((options, localizationMetadataProvider) =>
{
options.ModelMetadataDetailsProviders.Add(localizationMetadataProvider);
});
I tried to do the same thing with CookieAuthenticationOptions, but it doesn't appear to work the same way...
Upvotes: 4
Views: 1386
Reputation: 186
To use Dependency Injection with CookieAuthenticationOptions you must call the AddOptions<>()
and Configure<>()
methods before calling AddAuthentication()
or AddCookie()
authentication handlers.
Here is a sample DbContext with a User as the user model
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<User> Users { get; set; }
}
public class User
{
public string Id { get; set; }
public string CompanyId { get; set; }
}
The code to use dependency injection is below
services.AddOptions<CookieAuthenticationOptions>
(CookieAuthenticationDefaults.AuthenticationScheme)
.Configure<ApplicationDbContext>(async (options, context) =>
{
var user = new User
{
Id= Guid.NewGuid().ToString(),
CompanyId = Guid.NewGuid().ToString(),
};
Console.WriteLine($"------Adding user with DI {user.Id.ToString()}");
await context.Users.AddAsync(user);
await context.SaveChangesAsync();
});
When adding CookieAuthenticationOptions you must provide the name of the Auth Scheme because it is a named instance. CookieAuthenticationDefaults.AuthenticationScheme defaults to the value of "Cookies". You then can configure these options, and this is where dependency injection kicks in.
You must specify what you want to configure in the <>, and this object will be passed into the Configure()
method along with the named instance of CookieAuthenticationOptions that you are configuring.
The anonymous/lambda method is async (in this case I use it, but not required) and sends an instance of the options and the specified context into its method.
I create a user using the User class example from above. I create a dummy user to test this and then log the user's id to the console to easily spot it in your logs. I then add the user and save changes to the database and the changes are reflected. This only works/is called when the authentication handler is invoked (ex. logging in/out)
I found this answer based upon these links when attempting to use Redis as my session store and needed Dependency Injection. More Info below
https://stackoverflow.com/a/60394756/14465032
AspNet Core CookieAuthentication with injected SessionStore
Upvotes: 4
Reputation: 36645
For how to get the data from the database in cookie authentication options,here is a simple sample:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("YourConnnectionString")));
var sp = services.BuildServiceProvider();
var myDbContext = sp.GetService<MyDbContext>();
var data = GetData(myDbContext);
services.AddAuthentication(Authentication.scheme)
.AddCookie(Authentication.scheme,options =>
{
options.LoginPath = data;
//...
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//be sure you have added authentication middleware
app.UseAuthentication();
//if you use asp.net core 3.x,also need to add this
//app.UseAuthorization();
}
public static string GetData(MyDbContext _context)
{
//get the data from database
var data = _context.Tables.Select(j => j.Loginpath).FirstOrDefault();
return data;
}
Upvotes: 1