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)); }); }
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)); }); }
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); } } }; }); }