private void _view_Closing(object sender, EventArgs eventArgs) { if (eventArgs is not FormClosingEventArgs formEventArgs || formEventArgs.CloseReason != CloseReason.UserClosing || _formClosedManually) { return; } _cancellationTokenSource.Cancel(); _cancellationTokenSource.Dispose(); Initalizer.Quit(); }
/// <summary> /// ConfigureServices /// </summary> /// <param name="services"></param> public override void ConfigureServices(IServiceCollection services) { // Background Service services.AddSingleton <IBackgroundTask, IdleBackgroundTask>(); // Cache services.AddDistributedRedisCache(options => { options.Configuration = "localhost"; options.InstanceName = _environment.ApplicationName + ":"; }); services.AddMemoryCache(); // Cors services.AddCors(options => options.AddPolicy("DefaultPolicy", builder => builder.WithOrigins("http://localhost:9090", "http://localhost:8080").AllowAnyMethod().AllowAnyHeader().AllowCredentials()) // builder => builder.AllowAnyOrigin.AllowAnyMethod().AllowAnyHeader().AllowCredentials()) ); // Cookie services.Configure <CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => false; // 需保持为 false, 否则 Web API 不会 Set-Cookie 。 options.MinimumSameSitePolicy = SameSiteMode.None; }); // Session services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(10); options.Cookie.Name = ".Tubumu.Session"; options.Cookie.HttpOnly = true; }); // HTTP Client services.AddHttpClient(); // ApiBehaviorOptions services.Configure <ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = context => new OkObjectResult(new ApiResult { Code = 400, Message = context.ModelState.FirstErrorMessage() }); }); // Authentication var registeredServiceDescriptor = services.FirstOrDefault(s => s.Lifetime == ServiceLifetime.Transient && s.ServiceType == typeof(IApplicationModelProvider) && s.ImplementationType == typeof(AuthorizationApplicationModelProvider)); if (registeredServiceDescriptor != null) { services.Remove(registeredServiceDescriptor); } services.AddTransient <IApplicationModelProvider, PermissionAuthorizationApplicationModelProvider>(); services.AddSingleton <ITokenService, TokenService>(); var tokenValidationSettings = _configuration.GetSection("TokenValidationSettings").Get <TokenValidationSettings>(); services.AddSingleton(tokenValidationSettings); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidIssuer = tokenValidationSettings.ValidIssuer, ValidateIssuer = true, ValidAudience = tokenValidationSettings.ValidAudience, ValidateAudience = true, IssuerSigningKey = SignatureHelper.GenerateSigningKey(tokenValidationSettings.IssuerSigningKey), ValidateIssuerSigningKey = tokenValidationSettings.ValidateLifetime, ValidateLifetime = true, ClockSkew = TimeSpan.FromSeconds(tokenValidationSettings.ClockSkewSeconds), }; // 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. options.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("/hubs")) { // Read the token out of the query string context.Token = accessToken; } return(Task.CompletedTask); }, OnAuthenticationFailed = context => { _logger.LogError($"Authentication Failed(OnAuthenticationFailed): {context.Request.Path} Error: {context.Exception}"); if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { context.Response.Headers.Add("Token-Expired", "true"); } return(Task.CompletedTask); }, OnChallenge = context => { _logger.LogError($"Authentication Challenge(OnChallenge): {context.Request.Path}"); // TODO: (alby)为不同客户端返回不同的内容 var result = new ApiResultUrl() { Code = 400, Message = "Authentication Challenge", Url = _environment.IsProduction() ? tokenValidationSettings.LoginUrl : null, }; var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(result)); context.Response.StatusCode = StatusCodes.Status401Unauthorized; context.Response.ContentType = "application/json"; context.Response.Body.Write(body, 0, body.Length); context.HandleResponse(); return(Task.CompletedTask); } }; }); // JSON Date format void JsonSetup(MvcJsonOptions options) => options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; services.Configure((Action <MvcJsonOptions>)JsonSetup); // SignalR services.AddSignalR(); services.Replace(ServiceDescriptor.Singleton(typeof(IUserIdProvider), typeof(NameUserIdProvider))); // AutoMapper services.AddAutoMapper(); Initalizer.Initialize(); // Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = _environment.ApplicationName + " API", Version = "v1" }); c.AddSecurityDefinition("Bearer", new ApiKeyScheme { Description = "权限认证(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"", Name = "Authorization", In = "header", Type = "apiKey" }); var security = new Dictionary <string, IEnumerable <string> > { { "Bearer", new string[] { } }, }; c.AddSecurityRequirement(security); c.DescribeAllEnumsAsStrings(); c.DocumentFilter <HiddenApiDocumentFilter>(); IncludeXmlCommentsForModules(c); c.OrderActionsBy(m => m.ActionDescriptor.DisplayName); }); }