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