public SeekHub(UserManager <AppUser> userManager, SeekPool pool) : base() { Pool = pool; UserManager = userManager; }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddSignalR(); // In production, the React files will be served from this directory services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp/build"; }); // add Entity framework with migrations assembly for the project "OthelloServer" services.AddDbContext <ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly("OthelloServer"))); // add identity // Injects UserManager IdentityBuilder builder = services.AddIdentityCore <AppUser>(o => { o.User.RequireUniqueEmail = true; // configure identity options o.Password.RequireDigit = false; o.Password.RequireLowercase = false; o.Password.RequireUppercase = false; o.Password.RequireNonAlphanumeric = false; o.Password.RequiredLength = 6; }).AddEntityFrameworkStores <ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() .Build(); }); services.AddAuthentication(authOptions => { authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; authOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(jwtOptions => { jwtOptions.SaveToken = true; jwtOptions.ClaimsIssuer = Configuration["Authentication:Issuer"]; jwtOptions.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = Configuration["JwtAuthentication:Issuer"], ValidateAudience = true, ValidAudience = Configuration["JwtAuthentication:Audience"], ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey( Encoding.ASCII.GetBytes(Configuration["JwtAuthentication:SecretKey"])), RequireExpirationTime = false, ValidateLifetime = true, ClockSkew = TimeSpan.Zero }; // We have to hook the OnMessageReceived event in order to // allow the JWT authentication handler to read the access // token from the query string when a WebSocket or // Server-Sent Events request comes in. jwtOptions.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; // If the request is for our hub... var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/socket/seek") || path.StartsWithSegments("/socket/game"))) { // Read the token out of the query string context.Token = accessToken; } return(Task.CompletedTask); } }; }); services.AddSingleton(Configuration); SeekPool pool = new SeekPool(); services.AddSingleton(pool); // Change to use Name as the user identifier for SignalR // WARNING: This requires that the source of your JWT token // ensures that the Name claim is unique! // If the Name claim isn't unique, users could receive messages // intended for a different user! //services.AddSingleton<IUserIdProvider, NameUserIdProvider>(); // Change to use email as the user identifier for SignalR // services.AddSingleton<IUserIdProvider, EmailBasedUserIdProvider>(); // WARNING: use *either* the NameUserIdProvider *or* the // EmailBasedUserIdProvider, but do not use both. }