From e727ffdedc4314e764b63a3c35067030f61fb881 Mon Sep 17 00:00:00 2001 From: Ricardo Carneiro Date: Thu, 21 Aug 2025 21:29:00 -0300 Subject: [PATCH 1/2] fix: program.cs --- src/BCards.Web/Program.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/BCards.Web/Program.cs b/src/BCards.Web/Program.cs index 243a2c6..8f148c2 100644 --- a/src/BCards.Web/Program.cs +++ b/src/BCards.Web/Program.cs @@ -3,12 +3,10 @@ using BCards.Web.Services; using BCards.Web.Repositories; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Google; -using Microsoft.AspNetCore.Authentication.MicrosoftAccount; using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Options; using MongoDB.Driver; using System.Globalization; -using Stripe; using Microsoft.AspNetCore.Authentication.OAuth; using SendGrid; using BCards.Web.Middleware; @@ -295,4 +293,4 @@ using (var scope = app.Services.CreateScope()) app.Run(); // Make Program accessible for integration tests -public partial class Program { } \ No newline at end of file +public partial class Program { } -- 2.45.2 From def712bffe4a3e92eb00614b4f16cb386d8d7c42 Mon Sep 17 00:00:00 2001 From: Ricardo Carneiro Date: Thu, 21 Aug 2025 21:50:04 -0300 Subject: [PATCH 2/2] fix: redirect_uri ms --- src/BCards.Web/Program.cs | 102 ++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 16 deletions(-) diff --git a/src/BCards.Web/Program.cs b/src/BCards.Web/Program.cs index 8f148c2..33410c9 100644 --- a/src/BCards.Web/Program.cs +++ b/src/BCards.Web/Program.cs @@ -3,10 +3,12 @@ using BCards.Web.Services; using BCards.Web.Repositories; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Google; +using Microsoft.AspNetCore.Authentication.MicrosoftAccount; using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Options; using MongoDB.Driver; using System.Globalization; +using Stripe; using Microsoft.AspNetCore.Authentication.OAuth; using SendGrid; using BCards.Web.Middleware; @@ -15,6 +17,17 @@ using Microsoft.AspNetCore.HttpOverrides; var builder = WebApplication.CreateBuilder(args); +// 🔥 CONFIGURAR FORWARDED HEADERS NO BUILDER +builder.Services.Configure(options => +{ + options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; + options.RequireHeaderSymmetry = false; + options.KnownNetworks.Clear(); + options.KnownProxies.Clear(); + // 🚨 PERMITIR QUALQUER PROXY (NGINX) + options.ForwardLimit = null; +}); + // Add services to the container. builder.Services.AddControllersWithViews() .AddRazorRuntimeCompilation() @@ -83,23 +96,43 @@ builder.Services.AddAuthentication(options => options.AuthorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"; options.TokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token"; + // 🔥 SOLUÇÃO RADICAL: SEMPRE FORÇAR HTTPS options.Events = new OAuthEvents { OnRedirectToAuthorizationEndpoint = context => { - // 1. Força HTTPS em produção - if (!builder.Environment.IsDevelopment()) + var logger = context.HttpContext.RequestServices.GetRequiredService>(); + + // Debug info + logger.LogWarning($"=== MICROSOFT AUTH DEBUG ==="); + logger.LogWarning($"Original RedirectUri: {context.RedirectUri}"); + logger.LogWarning($"Request Scheme: {context.Request.Scheme}"); + logger.LogWarning($"Request IsHttps: {context.Request.IsHttps}"); + logger.LogWarning($"Request Host: {context.Request.Host}"); + logger.LogWarning($"X-Forwarded-Proto: {context.Request.Headers["X-Forwarded-Proto"]}"); + + // 🚨 FORÇA HTTPS SEMPRE (exceto localhost) + var originalUri = context.RedirectUri; + + // Se contém bcards.site, força HTTPS + if (originalUri.Contains("bcards.site")) { - context.RedirectUri = context.RedirectUri.Replace("http://", "https://"); + context.RedirectUri = originalUri + .Replace("http://bcards.site", "https://bcards.site") + .Replace("http%3A%2F%2Fbcards.site", "https%3A%2F%2Fbcards.site"); + + logger.LogWarning($"FORCED HTTPS - Modified RedirectUri: {context.RedirectUri}"); } - // 2. Adiciona prompt=login para forçar seleção de conta + // Adiciona prompt=login para forçar seleção de conta var redirectUri = context.RedirectUri; if (!redirectUri.Contains("prompt=")) { redirectUri += "&prompt=login"; } + logger.LogWarning($"Final RedirectUri: {redirectUri}"); + context.Response.Redirect(redirectUri); return Task.CompletedTask; } @@ -127,7 +160,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddSingleton(); +builder.Services.AddSingleton(); //builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -177,14 +210,26 @@ builder.Services.AddRazorPages(); var app = builder.Build(); -app.UseForwardedHeaders(new ForwardedHeadersOptions +// 🔥 PRIMEIRA COISA APÓS BUILD - FORWARDED HEADERS + BASE URL OVERRIDE +app.UseForwardedHeaders(); + +// 🚨 FORÇA BASE URL HTTPS EM PRODUÇÃO +if (!app.Environment.IsDevelopment()) { - ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, - // Permitir qualquer proxy (necessário para NGINX) - RequireHeaderSymmetry = false, - KnownNetworks = { }, - KnownProxies = { } -}); + app.Use(async (context, next) => + { + // Força o contexto a pensar que está em HTTPS + context.Request.Scheme = "https"; + + // Override do Host se necessário + if (context.Request.Host.Host == "bcards.site") + { + context.Request.Host = new HostString("bcards.site", 443); + } + + await next(); + }); +} // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) @@ -209,12 +254,38 @@ app.UseMiddleware(); app.UseMiddleware(); app.UseMiddleware(); +// 🔥 DEBUG MIDDLEWARE MELHORADO app.Use(async (context, next) => { + // Debug geral Console.WriteLine($"=== REQUEST DEBUG ==="); Console.WriteLine($"Path: {context.Request.Path}"); Console.WriteLine($"Query: {context.Request.QueryString}"); Console.WriteLine($"Method: {context.Request.Method}"); + Console.WriteLine($"Scheme: {context.Request.Scheme}"); + Console.WriteLine($"IsHttps: {context.Request.IsHttps}"); + Console.WriteLine($"Host: {context.Request.Host}"); + + // Debug específico para Microsoft signin + if (context.Request.Path.StartsWithSegments("/signin-microsoft")) + { + var logger = context.RequestServices.GetRequiredService>(); + logger.LogWarning($"=== SIGNIN-MICROSOFT CALLBACK DEBUG ==="); + logger.LogWarning($"Path: {context.Request.Path}"); + logger.LogWarning($"Query: {context.Request.QueryString}"); + logger.LogWarning($"Method: {context.Request.Method}"); + logger.LogWarning($"Scheme: {context.Request.Scheme}"); + logger.LogWarning($"IsHttps: {context.Request.IsHttps}"); + logger.LogWarning($"Host: {context.Request.Host}"); + logger.LogWarning($"X-Forwarded-Proto: {context.Request.Headers["X-Forwarded-Proto"]}"); + logger.LogWarning($"X-Forwarded-For: {context.Request.Headers["X-Forwarded-For"]}"); + logger.LogWarning($"All Headers:"); + foreach (var header in context.Request.Headers) + { + logger.LogWarning($" {header.Key}: {header.Value}"); + } + } + await next(); }); @@ -260,13 +331,12 @@ app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); - // Initialize default data using (var scope = app.Services.CreateScope()) { var themeService = scope.ServiceProvider.GetRequiredService(); var categoryService = scope.ServiceProvider.GetRequiredService(); - + try { // Initialize themes @@ -275,7 +345,7 @@ using (var scope = app.Services.CreateScope()) { await themeService.InitializeDefaultThemesAsync(); } - + // Initialize categories var existingCategories = await categoryService.GetAllCategoriesAsync(); if (!existingCategories.Any()) @@ -293,4 +363,4 @@ using (var scope = app.Services.CreateScope()) app.Run(); // Make Program accessible for integration tests -public partial class Program { } +public partial class Program { } \ No newline at end of file -- 2.45.2