public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy(DebugPolicyName, b => b.AllowAnyMethod() .AllowAnyHeader() .AllowCredentials() // only for the vue development server .WithOrigins("http://localhost:8080")); }); services.AddDbContext <GameDbContext>(builder => builder.UseSqlite(Configuration.GetConnectionString("Default"), b => b.MigrationsAssembly(nameof(WerewolfCircle)))); IConfiguration jwtConfiguration = Configuration.GetSection("Jwt"); services.AddOptions <JwtConfig>() .Bind(jwtConfiguration); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { JwtConfig jwtConfig = jwtConfiguration.Get <JwtConfig>(); options.RequireHttpsMetadata = !WebHostEnvironment.IsDevelopment(); options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters { RequireExpirationTime = true, RequireSignedTokens = true, RequireAudience = true, SaveSigninToken = false, TryAllIssuerSigningKeys = true, ValidateActor = false, ValidateAudience = true, ValidateIssuer = true, ValidateIssuerSigningKey = false, ValidateLifetime = true, ValidateTokenReplay = false, ValidIssuer = jwtConfig.Issuer, ValidAudience = jwtConfig.Audience, IssuerSigningKey = jwtConfig.BuildSecretSecurityKey(), ClockSkew = TimeSpan.Zero, // These two things need to be done since we don't want to use Microsofts claim names (see Program.cs). NameClaimType = JwtRegisteredClaimNames.GivenName, // set User.Identity.Name to the player name (which is unique within the game). RoleClaimType = JwtConfig.RoleClaimType // respect the specified role for authorization. }; options.Events = new JwtBearerEvents { OnMessageReceived = context => { StringValues accessToken = context.Request.Query["access_token"]; PathString path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments(GameHubRoute)) { // Read the token out of the query string (browser limitation for WebSockets) context.Token = accessToken; } return(Task.CompletedTask); } }; }); services.AddAuthorization(options => { options.AddPolicy(Policies.AdminPolicyName, Policies.BuildAdminPolicy()); }); services.AddControllers(); services.AddSignalR(); services.AddSingleton <IUserIdProvider, NameUserIdProvider>(); services.AddTransient <IRoomIdGenerator, NanoRoomIdGenerator>(); services.AddTransient <IAuthTokenGenerator, JwtTokenGenerator>(); }