Skip to content

Aguafrommars/DynamicAuthProviders

Repository files navigation

DynamicAuthProviders

Store and manage Microsoft.AspNetCore.Authentication providers dynamicaly.

Build status Quality Gate Status CII Best Practices

Nuget packages

Dynamic Provider EntityFramework Store Redis Store RavenDB Store Tests 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.