// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { var connectionString = Configuration.GetConnectionString("DefaultConnection"); services.AddDbContext <ApplicationDbContext>( options => options.UseSqlServer(connectionString, f => f.UseNetTopologySuite())); services.AddDbContext <AppDbContext>( options => options.UseSqlServer(connectionString)); services.AddDefaultIdentity <ApplicationUser>(options => { options.SignIn.RequireConfirmedAccount = false; }) .AddRoles <IdentityRole>() .AddEntityFrameworkStores <ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddIdentityServer() .AddApiAuthorization <ApplicationUser, ApplicationDbContext>() .AddProfileService <CProfileService>(); services.AddTransient <IEmailSender, TwilloMailService>(); services.AddSingleton <UserLocationTracker>(); services.AddSingleton <IMapper>(new Mapper(new MapperConfiguration(expression => { expression.AddProfile(new EFModelMapProfile()); }))); services.Configure <AuthMessageSenderOptions>(Configuration); // Or configure recaptcha via options services.AddRecaptcha(Configuration.GetSection("RecaptchaSettings")); //IdentityModelEventSource.ShowPII = true; services.AddAuthorization(options => { options.AddPolicy("IsReviewer", builder => { builder.RequireRole("Reviewer"); }); }); services.AddAuthentication(x => { }) .AddIdentityServerJwt() .AddCookie() .AddOAuth("Frontier", "Frontier", options => { var httpsAuthFrontierstoreNet = "https://auth.frontierstore.net"; options.AuthorizationEndpoint = $"{httpsAuthFrontierstoreNet}/auth"; options.Scope.Add("auth"); options.Scope.Add("capi"); options.CallbackPath = "/auth-callback/frontier"; options.ClientId = "24592b33-5595-4fa8-b7ec-bbcc10b83755"; //its ok, in the end this is publicly readable options.ClientSecret = "None"; options.TokenEndpoint = $"{httpsAuthFrontierstoreNet}/token"; options.UserInformationEndpoint = $"{httpsAuthFrontierstoreNet}/me"; options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "customer_id"); options.ClaimActions.MapJsonKey(ClaimTypes.Name, "firstname"); options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email"); options.UsePkce = true; options.Events = new OAuthEvents { OnRemoteFailure = async context => { }, OnAccessDenied = async context => { }, OnTicketReceived = async context => { var identity = context.Principal.Identity as ClaimsIdentity; identity.AddClaim(new Claim("NOOOOOOOOOOOOOOPE", "Value")); }, OnCreatingTicket = async context => { // Get user info from the userinfo endpoint and use it to populate user claims var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted); response.EnsureSuccessStatusCode(); var user = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); context.RunClaimActions(user.RootElement); var frontierApi = new FrontierApi(); var dataFor = await frontierApi.GetDataFor(context.AccessToken); context.Identity.AddClaim(new Claim(FrontierClaims.CommanderName, dataFor.Commander.Name)); context.Identity.AddClaim(new Claim("frontier:user:commanderId", dataFor.Commander.Id.ToString())); context.Identity.AddClaim(new Claim("frontier:token", context.AccessToken)); context.Identity.AddClaim(new Claim("frontier:refreshtoken", context.RefreshToken)); context.Identity.AddClaim(new Claim("frontier:tokenvalid", (context.ExpiresIn?.TotalSeconds ?? 3600).ToString())); }, OnRedirectToAuthorizationEndpoint = context => { //var codeVerifier = CryptoRandom.CreateUniqueId(32); //context.Properties.Items.Add("codeVerifier", codeVerifier); //string codeChallenge; //using (var sha256 = SHA256.Create()) //{ // var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier)); // codeChallenge = Base64Url.Encode(challengeBytes); //} //context.RedirectUri += $"&audience=frontier&code_challenge={codeChallenge}&code_challenge_method=S256"; context.Response.Redirect(context.RedirectUri); return(Task.CompletedTask); }, }; }); services.AddControllersWithViews(); services.AddRazorPages(); services.Configure <IdentityOptions>(options => { // Password settings. options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = true; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 1; // Lockout settings. options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // User settings. options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; options.User.RequireUniqueEmail = false; }); //services.ConfigureApplicationCookie(options => //{ // // Cookie settings // options.Cookie.HttpOnly = true; // options.ExpireTimeSpan = TimeSpan.FromHours(5); // options.LoginPath = "/Identity/Account/Login"; // options.AccessDeniedPath = "/Identity/Account/AccessDenied"; // options.SlidingExpiration = true; //}); services.AddSingleton(provider => { var service = provider.GetService <ILogger <ITask> >(); var scheduler = new Scheduler(service); scheduler.AddByAttributes(Assembly.GetCallingAssembly()); scheduler.AddByAttributes(typeof(BaseTask).Assembly); scheduler.OnFailedTask += (task, exception, handler) => { service.LogError("The task with the name " + task.NamedTask + " has failed", new Dictionary <string, string> { { "Exception", exception.ToString() } }); }; scheduler.Start(); return(scheduler); }); }