using Hangfire; using Hangfire.Redis.StackExchange; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using TEAMModelOS.SDK.DI; using TEAMModelOS.SDK; using HTEX.Complex.Services; using HTEX.Complex.Services.MQTT; using MathNet.Numerics; using MQTTnet.AspNetCore; using MQTTnet.Server; using Microsoft.Extensions.Options; using System.Threading; using Microsoft.Extensions.Logging; using System.Text.Json; using Microsoft.Extensions.Hosting; using MQTTnet.AspNetCore.Routing; using Microsoft.AspNetCore.Builder; namespace HTEX.Complex { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); //builder.WebHost.ConfigureKestrel(options => //{ // //options.ListenAnyIP(4001, options => { // // // options.UseHttps("Crt/iteden.pfx", "iteden"); // //}); // options.ListenAnyIP(1883, options => { options.UseMqtt();/*options.UseHttps("Crt/iteden.pfx", "iteden");*/ }); // options.ListenAnyIP(1884, options => { options.UseMqtt();/* options.UseHttps("Configs/Crt/iteden.pfx", "iteden"); */}); // Default HTTP pipeline //}); //builder.WebHost.ConfigureKestrel(options => //{ // //options.ListenAnyIP(4001, options => { // // // options.UseHttps("Crt/iteden.pfx", "iteden"); // //}); // options.ListenAnyIP(1883, options => { options.UseMqtt();/*options.UseHttps("Crt/iteden.pfx", "iteden");*/ }); // options.ListenAnyIP(1884, options => { options.UseMqtt();/* options.UseHttps("Configs/Crt/iteden.pfx", "iteden"); */}); // Default HTTP pipeline //}); // Add services to the container. JwtSecurityTokenHandler.DefaultMapInboundClaims = false; builder.Services.AddAuthentication(options => options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => //AzureADJwtBearer { //options.SaveToken = true; //驗證令牌由服務器生成才有效,不適用於服務重啟或分布式架構 options.Authority ="https://login.chinacloudapi.cn/4807e9cf-87b8-4174-aa5b-e76497d7392b/v2.0";// builder.Configuration["Option:Authority"]; options.Audience = "72643704-b2e7-4b26-b881-bd5865e7a7a5";//builder.Configuration["Option:Audience"]; options.RequireHttpsMetadata = true; options.TokenValidationParameters = new TokenValidationParameters { RoleClaimType = "roles", //ValidAudiences = new string[] { builder.Configuration["Option:Audience"], $"api://{builder.Configuration["Option:Audience"]}" } ValidAudiences = new string[] { "72643704-b2e7-4b26-b881-bd5865e7a7a5", $"api://72643704-b2e7-4b26-b881-bd5865e7a7a5" } }; options.Events = new JwtBearerEvents(); //下列事件有需要紀錄則打開 //options.Events.OnMessageReceived = async context => { await Task.FromResult(0); }; //options.Events.OnForbidden = async context => { await Task.FromResult(0); }; //options.Events.OnChallenge = async context => { await Task.FromResult(0); }; //options.Events.OnAuthenticationFailed = async context => { await Task.FromResult(0); }; options.Events.OnTokenValidated = async context => { if (!context.Principal.Claims.Any(x => x.Type.Equals("http://schemas.microsoft.com/identity/claims/scope")) //ClaimConstants.Scope && !context.Principal.Claims.Any(y => y.Type.Equals("roles"))) //ClaimConstants.Roles //http://schemas.microsoft.com/ws/2008/06/identity/claims/role { //TODO 需處理額外授權非角色及範圍的訪問異常紀錄 throw new UnauthorizedAccessException("Neither scope or roles claim was found in the bearer token."); } await Task.FromResult(0); }; }); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); builder.Services.AddHttpClient(); string? StorageConnectionString = builder.Configuration.GetValue("Azure:Storage:ConnectionString"); string? RedisConnectionString = builder.Configuration.GetValue("Azure:Redis:ConnectionString"); //Storage builder.Services.AddAzureStorage(StorageConnectionString, "Default"); //Redis builder.Services.AddAzureRedis(RedisConnectionString, "Default"); string? StorageConnectionStringTest = builder.Configuration.GetValue("Azure:Storage:ConnectionString-Test"); //Storage builder.Services.AddAzureStorage(StorageConnectionStringTest, "Test"); builder.Services.AddSignalR(); builder.Services.AddHttpContextAccessor(); builder.Services.AddHttpClient(); string path = $"{builder.Environment.ContentRootPath}/JsonFiles"; builder.Services.TryAddSingleton(new Region2LongitudeLatitudeTranslator(path)); builder.Services.AddIPSearcher(path); builder.Services.AddCors(options => { options.AddDefaultPolicy( builder => { builder.AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod(); }); }); builder.Services.AddControllersWithViews(); //MQTT 服务端API 发送消息到MQTT客户端 https://www.cnblogs.com/weskynet/p/16441219.html #region MQTT配置 builder.Services.AddSingleton(); builder.Services.AddSingleton(new JsonSerializerOptions(JsonSerializerDefaults.Web)); builder.Services.AddHostedMqttServerWithServices(x => { x.WithDefaultEndpoint() .WithConnectionBacklog(1000) .WithPersistentSessions(true).WithKeepAlive() .WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(30)); }).AddMqttConnectionHandler().AddConnections().AddMqttControllers(); #endregion var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseRouting(); app.UseCors(); //使用跨域設定 app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.MapHub("/signalr/screen").RequireCors("any"); app.MapConnectionHandler("/mqtt", opts => opts.WebSockets.SubProtocolSelector = protocolList => protocolList.FirstOrDefault() ?? string.Empty); var events = app.Services.GetRequiredService(); app.UseMqttServer(server => { server.WithAttributeRouting(app.Services, allowUnmatchedRoutes: false); server.ClientSubscribedTopicAsync+=events._mqttServer_ClientSubscribedTopicAsync;// 客户端订阅主题事件 server.StoppedAsync+=events._mqttServer_StoppedAsync;// 关闭后事件 server.ValidatingConnectionAsync+=events._mqttServer_ValidatingConnectionAsync; // 用户名和密码验证有关 server.InterceptingPublishAsync+=events._mqttServer_InterceptingPublishAsync;// 消息接收事件 server.StartedAsync+=events._mqttServer_StartedAsync;// 启动后事件 server.ClientUnsubscribedTopicAsync+=events._mqttServer_ClientUnsubscribedTopicAsync;// 客户端取消订阅事件 server.ApplicationMessageNotConsumedAsync+=events._mqttServer_ApplicationMessageNotConsumedAsync; // 消息接收事件,应用程序消息未使用 server.ClientDisconnectedAsync+=events._mqttServer_ClientDisconnectedAsync;// 客户端关闭事件 server.ClientConnectedAsync+=events._mqttServer_ClientConnectedAsync;//客户端连接事件 //server.InterceptingClientEnqueueAsync += events._mqttServer_InterceptingClientEnqueueAsync;//拦截客户端排队 //server.ClientAcknowledgedPublishPacketAsync += events._mqttServer_ClientAcknowledgedPublishPacketAsync;//已确认发布数据包 }); app.Run(); } } }