DynamicAuthProviders

February 18, 2021 ยท View on GitHub

Store and manage Microsoft.AspNetCore.Authentication providers dynamicaly.

Build status Quality Gate Status CII Best Practices

Nuget packages

Dynamic ProviderEntityFramework StoreRedis StoreRavenDB StoreTests Suite

Setup

In your Startup ConfigureServices method, add the following:

/** Add dynamic management **/

// Add the context to store schemes configurations.
// The context can be any kind of DbContext having a DbSet<TSchemeDefinition>
// where TSchemeDefinition is of type SchemeDefinition or derived.
services.AddDbContext<SchemeDbContext>(options =>
{
    options.UseSqlServer(Configuration.GetConnectionString("Default"));
}); 

// Add authentication
var authBuilder = services
    .AddAuthentication();

// Add the magic
var dynamicBuilder = authBuilder
    .AddDynamic<SchemeDefinition>()
    .AddEntityFrameworkStore<SchemeDbContext>();

// Add providers managed dynamically
dynamicBuilder.AddGoogle()
    .AddOAuth("Github", "Github", options =>
    {
        // You can define default configuration for managed handlers.
        options.AuthorizationEndpoint = "https://github.com/login/oauth/authorize";
        options.TokenEndpoint = "https://github.com/login/oauth/access_token";
        options.UserInformationEndpoint = "https://api.github.com/user";
        options.ClaimsIssuer = "OAuth2-Github";
        // Retrieving user information is unique to each provider.
        options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
        options.ClaimActions.MapJsonKey(ClaimTypes.Name, "login");
        options.ClaimActions.MapJsonKey("urn:github:name", "name");
        options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email", ClaimValueTypes.Email);
        options.ClaimActions.MapJsonKey("urn:github:url", "url");
        options.Events = new OAuthEvents
        {
            OnCreatingTicket = async context =>
            {
                // Get the GitHub user
                var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                // A user-agent header is required by GitHub. See (https://developer.github.com/v3/#user-agent-required)
                request.Headers.UserAgent.Add(new ProductInfoHeaderValue("DynamicAuthProviders-sample", "1.0.0"));

                var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted);
                var content = await response.Content.ReadAsStringAsync();
                response.EnsureSuccessStatusCode();

                var user = JObject.Parse(content);

                context.RunClaimActions(user);
            }
        };
    }); 

And in the Configure method load the configuration with LoadDynamicAuthenticationConfiguration method:


    app.UseHttpsRedirection()
        .UseStaticFiles()
        .UseCookiePolicy()
        .UseAuthentication()
        .UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        })
        // load dynamyc authentication configuration from store
        .LoadDynamicAuthenticationConfiguration();

Read the wiki for more information.