private void ConfigureAuthServices(IServiceCollection services)
        {
            services.AddIdentity <ApplicationUser, IdentityRole <int> >(
                options => { options.Lockout.AllowedForNewUsers = false; })
            .AddEntityFrameworkStores <BuildAssetRegistryContext>();

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = options.DefaultChallengeScheme = options.DefaultScheme = "Contextual";
                options.DefaultSignInScheme       = IdentityConstants.ExternalScheme;
            })
            .AddPolicyScheme("Contextual", "Contextual",
                             policyOptions => { policyOptions.ForwardDefaultSelector = ctx => ctx.Request.Path.StartsWithSegments("/api") ? PersonalAccessTokenDefaults.AuthenticationScheme : IdentityConstants.ApplicationScheme; })
            .AddGitHubOAuth(Configuration.GetSection("GitHubAuthentication"), GitHubScheme)
            .AddPersonalAccessToken <ApplicationUser>(
                options =>
            {
                options.Events = new PersonalAccessTokenEvents <ApplicationUser>
                {
                    OnSetTokenHash = async context =>
                    {
                        var dbContext = context.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        int userId = context.User.Id;
                        var token  = new ApplicationUserPersonalAccessToken
                        {
                            ApplicationUserId = userId,
                            Name    = context.Name,
                            Hash    = context.Hash,
                            Created = DateTimeOffset.UtcNow
                        };
                        await dbContext.Set <ApplicationUserPersonalAccessToken>().AddAsync(token);
                        await dbContext.SaveChangesAsync();

                        return(token.Id);
                    },
                    OnGetTokenHash = async context =>
                    {
                        var dbContext = context.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        ApplicationUserPersonalAccessToken token = await dbContext
                                                                   .Set <ApplicationUserPersonalAccessToken>()
                                                                   .Where(t => t.Id == context.TokenId)
                                                                   .Include(t => t.ApplicationUser)
                                                                   .FirstOrDefaultAsync();
                        if (token != null)
                        {
                            context.Success(token.Hash, token.ApplicationUser);
                        }
                    },
                    OnValidatePrincipal = async context =>
                    {
                        ApplicationUser user = context.User;
                        var dbContext        = context.HttpContext.RequestServices
                                               .GetRequiredService <BuildAssetRegistryContext>();
                        var userManager = context.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        var signInManager = context.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();
                        var gitHubClaimResolver = context.HttpContext.RequestServices
                                                  .GetRequiredService <GitHubClaimResolver>();

                        await UpdateUserIfNeededAsync(user, dbContext, userManager, signInManager, gitHubClaimResolver);

                        ClaimsPrincipal principal = await signInManager.CreateUserPrincipalAsync(user);
                        context.ReplacePrincipal(principal);
                    }
                };
            });
            services.ConfigureExternalCookie(
                options =>
            {
                options.ExpireTimeSpan     = TimeSpan.FromMinutes(30);
                options.ReturnUrlParameter = "returnUrl";
                options.LoginPath          = "/Account/SignIn";
                options.Events             = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = ctx =>
                    {
                        if (ctx.Request.Path.StartsWithSegments("/api"))
                        {
                            ctx.Response.StatusCode = 401;
                            return(Task.CompletedTask);
                        }

                        ctx.Response.Redirect(ctx.RedirectUri);
                        return(Task.CompletedTask);
                    },
                    OnRedirectToAccessDenied = ctx =>
                    {
                        ctx.Response.StatusCode = 403;
                        return(Task.CompletedTask);
                    },
                };
            });
            services.ConfigureApplicationCookie(
                options =>
            {
                options.ExpireTimeSpan     = LoginCookieLifetime;
                options.SlidingExpiration  = true;
                options.ReturnUrlParameter = "returnUrl";
                options.LoginPath          = "/Account/SignIn";
                options.Events             = new CookieAuthenticationEvents
                {
                    OnSigningIn = async ctx =>
                    {
                        var dbContext = ctx.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        var signInManager = ctx.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();
                        var userManager = ctx.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync();

                        var user = await userManager.GetUserAsync(ctx.Principal);
                        await UpdateUserTokenAsync(dbContext, userManager, user, info);

                        IdentityOptions identityOptions = ctx.HttpContext.RequestServices
                                                          .GetRequiredService <IOptions <IdentityOptions> >()
                                                          .Value;

                        // replace the ClaimsPrincipal we are about to serialize to the cookie with a reference
                        Claim claim = ctx.Principal.Claims.First(
                            c => c.Type == identityOptions.ClaimsIdentity.UserIdClaimType);
                        Claim[] claims = { claim };
                        var identity   = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme);
                        ctx.Principal  = new ClaimsPrincipal(identity);
                    },
                    OnValidatePrincipal = async ctx =>
                    {
                        var dbContext = ctx.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        var userManager = ctx.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        var signInManager = ctx.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();
                        var gitHubClaimResolver = ctx.HttpContext.RequestServices
                                                  .GetRequiredService <GitHubClaimResolver>();

                        // extract the userId from the ClaimsPrincipal and read the user from the Db
                        ApplicationUser user = await userManager.GetUserAsync(ctx.Principal);
                        if (user == null)
                        {
                            ctx.RejectPrincipal();
                        }
                        else
                        {
                            await UpdateUserIfNeededAsync(user, dbContext, userManager, signInManager, gitHubClaimResolver);

                            ClaimsPrincipal principal = await signInManager.CreateUserPrincipalAsync(user);
                            ctx.ReplacePrincipal(principal);
                        }
                    }
                };
            });

            services.AddAuthorization(
                options =>
            {
                options.AddPolicy(
                    MsftAuthorizationPolicyName,
                    policy =>
                {
                    policy.RequireAuthenticatedUser();
                    if (!HostingEnvironment.IsDevelopment())
                    {
                        policy.RequireRole(GitHubClaimResolver.GetTeamRole("dotnet", "dnceng"), GitHubClaimResolver.GetTeamRole("dotnet", "arcade-contrib"));
                    }
                });
            });

            services.Configure <MvcOptions>(
                options =>
            {
                options.Conventions.Add(new DefaultAuthorizeActionModelConvention(MsftAuthorizationPolicyName));
            });
        }
Exemple #2
0
        private void ConfigureAuthServices(IServiceCollection services)
        {
            services.AddIdentity <ApplicationUser, IdentityRole <int> >(
                options => { options.Lockout.AllowedForNewUsers = false; })
            .AddEntityFrameworkStores <BuildAssetRegistryContext>();

            services.AddSingleton <IAuthenticationSchemeProvider, ContextAwareAuthenticationSchemeProvider>();
            services.AddAuthentication()
            .AddOAuth <GitHubAuthenticationOptions, GitHubAuthenticationHandler>(
                GitHubScheme,
                options =>
            {
                IConfigurationSection ghAuthConfig = Configuration.GetSection("GitHubAuthentication");
                ghAuthConfig.Bind(options);
                options.Events = new OAuthEvents
                {
                    OnCreatingTicket = async context =>
                    {
                        var logger = context.HttpContext.RequestServices.GetRequiredService <ILogger <Startup> >();
                        logger.LogInformation("Reading user roles from GitHub.");
                        foreach (string role in await GetGithubRolesAsync(context.AccessToken))
                        {
                            context.Identity.AddClaim(
                                new Claim(ClaimTypes.Role, role, ClaimValueTypes.String, GitHubScheme));
                        }
                    },
                };
            })
            .AddPersonalAccessToken <ApplicationUser>(
                options =>
            {
                options.Events = new PersonalAccessTokenEvents <ApplicationUser>
                {
                    OnSetTokenHash = async context =>
                    {
                        var dbContext = context.HttpContext.RequestServices.GetRequiredService <BuildAssetRegistryContext>();
                        int userId    = context.User.Id;
                        var token     = new ApplicationUserPersonalAccessToken
                        {
                            ApplicationUserId = userId,
                            Name    = context.Name,
                            Hash    = context.Hash,
                            Created = DateTimeOffset.UtcNow
                        };
                        await dbContext.Set <ApplicationUserPersonalAccessToken>().AddAsync(token);
                        await dbContext.SaveChangesAsync();

                        return(token.Id);
                    },
                    OnGetTokenHash = async context =>
                    {
                        var dbContext = context.HttpContext.RequestServices.GetRequiredService <BuildAssetRegistryContext>();
                        ApplicationUserPersonalAccessToken token = await dbContext
                                                                   .Set <ApplicationUserPersonalAccessToken>()
                                                                   .Where(t => t.Id == context.TokenId)
                                                                   .Include(t => t.ApplicationUser)
                                                                   .FirstOrDefaultAsync();
                        if (token != null)
                        {
                            context.Success(token.Hash, token.ApplicationUser);
                        }
                    },
                    OnValidatePrincipal = async context =>
                    {
                        if (ShouldUpdateUser(context.User))
                        {
                            var dbContext = context.HttpContext.RequestServices
                                            .GetRequiredService <BuildAssetRegistryContext>();
                            var userManager = context.HttpContext.RequestServices
                                              .GetRequiredService <UserManager <ApplicationUser> >();
                            var signInManager = context.HttpContext.RequestServices
                                                .GetRequiredService <SignInManager <ApplicationUser> >();

                            await UpdateUserAsync(context.User, dbContext, userManager, signInManager);

                            context.ReplacePrincipal(await signInManager.CreateUserPrincipalAsync(context.User));
                        }
                    },
                };
            });
            services.ConfigureExternalCookie(
                options =>
            {
                options.ExpireTimeSpan     = TimeSpan.FromMinutes(30);
                options.ReturnUrlParameter = "returnUrl";
                options.LoginPath          = "/Account/SignIn";
                options.Events             = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = ctx =>
                    {
                        if (ctx.Request.Path.StartsWithSegments("/api"))
                        {
                            ctx.Response.StatusCode = 401;
                            return(Task.CompletedTask);
                        }

                        ctx.Response.Redirect(ctx.RedirectUri);
                        return(Task.CompletedTask);
                    },
                    OnRedirectToAccessDenied = ctx =>
                    {
                        ctx.Response.StatusCode = 403;
                        return(Task.CompletedTask);
                    }
                };
            });
            services.ConfigureApplicationCookie(
                options =>
            {
                options.ExpireTimeSpan    = TimeSpan.FromMinutes(30);
                options.SlidingExpiration = true;
                options.Events            = new CookieAuthenticationEvents
                {
                    OnSigningIn = ctx =>
                    {
                        IdentityOptions identityOptions = ctx.HttpContext.RequestServices
                                                          .GetRequiredService <IOptions <IdentityOptions> >()
                                                          .Value;

                        // replace the ClaimsPrincipal we are about to serialize to the cookie with a reference
                        Claim claim = ctx.Principal.Claims.Single(
                            c => c.Type == identityOptions.ClaimsIdentity.UserIdClaimType);
                        Claim[] claims = { claim };
                        var identity   = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme);
                        ctx.Principal  = new ClaimsPrincipal(identity);

                        return(Task.CompletedTask);
                    },
                    OnValidatePrincipal = async ctx =>
                    {
                        var dbContext = ctx.HttpContext.RequestServices
                                        .GetRequiredService <BuildAssetRegistryContext>();
                        var userManager = ctx.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        var signInManager = ctx.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();


                        // extract the userId from the ClaimsPrincipal and read the user from the Db
                        ApplicationUser user = await userManager.GetUserAsync(ctx.Principal);
                        if (user == null)
                        {
                            ctx.RejectPrincipal();
                        }
                        else
                        {
                            if (ShouldUpdateUser(user))
                            {
                                await UpdateUserAsync(user, dbContext, userManager, signInManager);
                            }

                            ClaimsPrincipal principal = await signInManager.CreateUserPrincipalAsync(user);
                            ctx.ReplacePrincipal(principal);
                        }
                    }
                };
            });

            services.AddAuthorization(
                options =>
            {
                options.AddPolicy(
                    MsftAuthorizationPolicyName,
                    policy =>
                {
                    policy.RequireAuthenticatedUser();
                    if (!HostingEnvironment.IsDevelopment())
                    {
                        policy.RequireRole(
                            "github:team:dotnet:dnceng",
                            "github:team:dotnet:arcade-contrib");
                    }
                });
            });

            services.Configure <MvcOptions>(
                options =>
            {
                options.Conventions.Add(new DefaultAuthorizeActionModelConvention(MsftAuthorizationPolicyName));
            });
        }
Exemple #3
0
        private void ConfigureAuthServices(IServiceCollection services)
        {
            services.AddIdentity <ApplicationUser, IdentityRole <int> >(
                options => { options.Lockout.AllowedForNewUsers = false; })
            .AddEntityFrameworkStores <BuildAssetRegistryContext>();

            services.AddSingleton <IAuthenticationSchemeProvider, ContextAwareAuthenticationSchemeProvider>();
            services.AddAuthentication()
            .AddOAuth <GitHubAuthenticationOptions, GitHubAuthenticationHandler>(
                GitHubScheme,
                options =>
            {
                IConfigurationSection ghAuthConfig = Configuration.GetSection("GitHubAuthentication");
                ghAuthConfig.Bind(options);
                options.Events = new OAuthEvents {
                    OnCreatingTicket = AddOrganizationRoles
                };
            })
            .AddPersonalAccessToken <ApplicationUser>(
                options =>
            {
                options.Events = new PersonalAccessTokenEvents <ApplicationUser>
                {
                    NewToken = async(context, user, name, hash) =>
                    {
                        var dbContext = context.RequestServices.GetRequiredService <BuildAssetRegistryContext>();
                        int userId    = user.Id;
                        var token     = new ApplicationUserPersonalAccessToken
                        {
                            ApplicationUserId = userId,
                            Name    = name,
                            Hash    = hash,
                            Created = DateTimeOffset.UtcNow
                        };
                        await dbContext.Set <ApplicationUserPersonalAccessToken>().AddAsync(token);
                        await dbContext.SaveChangesAsync();

                        return(token.Id);
                    },
                    GetTokenHash = async(context, tokenId) =>
                    {
                        var dbContext = context.RequestServices.GetRequiredService <BuildAssetRegistryContext>();
                        ApplicationUserPersonalAccessToken token = await dbContext
                                                                   .Set <ApplicationUserPersonalAccessToken>()
                                                                   .Where(t => t.Id == tokenId)
                                                                   .Include(t => t.ApplicationUser)
                                                                   .FirstOrDefaultAsync();
                        if (token == null)
                        {
                            return(null);
                        }

                        return(token.Hash, token.ApplicationUser);
                    }
                };
            });
            services.ConfigureExternalCookie(
                options =>
            {
                options.ExpireTimeSpan     = TimeSpan.FromMinutes(30);
                options.ReturnUrlParameter = "returnUrl";
                options.LoginPath          = "/Account/SignIn";
                options.Events             = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = ctx =>
                    {
                        if (ctx.Request.Path.StartsWithSegments("/api"))
                        {
                            ctx.Response.StatusCode = 401;
                            return(Task.CompletedTask);
                        }

                        ctx.Response.Redirect(ctx.RedirectUri);
                        return(Task.CompletedTask);
                    },
                    OnRedirectToAccessDenied = ctx =>
                    {
                        ctx.Response.StatusCode = 403;
                        return(Task.CompletedTask);
                    }
                };
            });
            services.ConfigureApplicationCookie(
                options =>
            {
                options.ExpireTimeSpan    = TimeSpan.FromMinutes(30);
                options.SlidingExpiration = true;
                options.Events            = new CookieAuthenticationEvents
                {
                    OnSigningIn = ctx =>
                    {
                        IdentityOptions identityOptions = ctx.HttpContext.RequestServices
                                                          .GetRequiredService <IOptions <IdentityOptions> >()
                                                          .Value;

                        // replace the ClaimsPrincipal we are about to serialize to the cookie with a reference
                        Claim claim = ctx.Principal.Claims.Single(
                            c => c.Type == identityOptions.ClaimsIdentity.UserIdClaimType);
                        Claim[] claims = { claim };
                        var identity   = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme);
                        ctx.Principal  = new ClaimsPrincipal(identity);

                        return(Task.CompletedTask);
                    },
                    OnValidatePrincipal = async ctx =>
                    {
                        var userManager = ctx.HttpContext.RequestServices
                                          .GetRequiredService <UserManager <ApplicationUser> >();
                        var signInManager = ctx.HttpContext.RequestServices
                                            .GetRequiredService <SignInManager <ApplicationUser> >();


                        // extract the userId from the ClaimsPrincipal and read the user from the Db
                        ApplicationUser user = await userManager.GetUserAsync(ctx.Principal);
                        if (user == null)
                        {
                            ctx.Principal = null;
                        }
                        else
                        {
                            ctx.Principal = await signInManager.CreateUserPrincipalAsync(user);
                        }
                    }
                };
            });
        }