I'm having some trouble with the whole dependency injection with/through reflection.
The scenario is as following;
- User authenticates via AzureAD through our identity server
- If user is not in local database, save the user together with some other information
I keep restructuring my logic and I still can't make the puzzle work.
Currently this is my chain:
OWIN Startup:
I'm specifying a method to run after the OnTokenValidated event has triggered: ProfileEvents.ValidatedToken
services.AddAuthentication()
.AddOpenIdConnect("oidc", o =>
{
o.ClientId = $"{configuration["Globals:AzureApplication:AppId"]}";
o.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
o.Authority = $"https://login.microsoftonline.com/{configuration["Globals:AzureApplication:TenantId"]}";
o.ResponseType = OpenIdConnectResponseType.CodeIdTokenToken;
o.Events = new OpenIdConnectEvents()
{
OnTokenValidated = ProfileEvents.ValidatedToken
};
});
DatabaseContext is added like this:
public void ConfigureServices(IServiceCollection services)
{
.... // other stuff
services.Configure<Config.ConnectionStrings>(configuration.GetSection("ConnectionStrings"));
services.AddDbContext<ModelContext>(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
}
The my ValidatedToken method looks like this:
internal static class ProfileEvents
{
internal static Task ValidatedToken(TokenValidatedContext context)
{
var dbContext = new ProfileDAL();
dbContext.SaveToDb(context.Principal);
return Task.FromResult(0);
}
}
And finally my ProfileDAL looks like this:
public class ProfileDAL
{
internal async Task SaveToDb(ClaimsPrincipal principal)
{
var nameClaim = principal.FindFirstValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn");
var emailClaim = principal.FindFirstValue("email");
// TODO: Save user..
}
}
Now which way I turn I either have to use and pass IOptions through the chain so that ModelContext can override "OnConfiguring" to actually get the connection string or I have to pass the context.
Is there really no way to access either the connection string outside of the DI?
For me I feel like something like this would solve all of my current issues:
public partial class ModelContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer( ** Magic way to access connection string in appsettings ** );
}
}