我有一个使用 Google 的 OAuth2.0 身份验证的 MVC .net core 6 Web 应用程序,但无法使用 Kubernetes 发布它。
项目背景:
它在本地正常编译和运行,包括创建 docker 映像并运行容器,但要在本地运行 docker 容器并拥有带有有效证书的 https 端口(我需要这个才能让 Google 的 OAuth 工作),我需要运行以下过程。
使本地证书可信的命令和过程序列(您只需在 docker 容器中运行即可执行此操作,无需直接运行项目):
创建本地证书 pfx: dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\Apresentacao.Web.pfx -p pa55w0rd!
在应用程序的 .csproj 中创建 UserScretsId 配置行:{SomeGuidIdHere}
在本地用户密码中输入证书密码: dotnet user-secrets set "Kestrel:Certificates:Development:Password" "pa55w0rd!"
使证书“受信任” dotnet dev-certs https --trust
运行 docker 容器,但传递一些必要的参数(在项目文件夹外的 powershell 或 bash 中运行):
docker run -p 8080:80 -p 8081:443 -e ASPNETCORE\_URLS="https://+;http://+" -e ASPNETCORE\_HTTPS\_PORT="8081" -e ASPNETCORE\_ENVIRONMENT=Development - v $env:APPDATA\microsoft\UserSecrets\\:/root/.microsoft/usersecrets -v $env:USERPROFILE\\.aspnet\https:/root/.aspnet/https/ admin
如果我不执行上述过程,或者执行“Docker run”而不传递使用 https 端口和证书所需的参数,则在运行容器时会收到以下返回结果:
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3] Failed to determine the https port for redirect.
我的问题是: 在本地,我找到了处理 docker 容器、https 端口和 localhost 的 ssl 证书的解决方案,但是我使用 Git Hub 操作在 Google Cloud 上发布相同的应用程序来运行我的部署管道,并在云中我我将镜像 docker 保存在存储桶中并使用 kubernetes 创建服务。我们已经有其他应用程序在带有 Kubernetes 的 Google 云基础设施上运行,并且我们可以毫无问题地通过 Ingress 公开 URL 并使用 Google 提供的证书。
我用不同的配置进行了几次发布测试,直到我怀疑它可能是应用程序中的某些内容,我决定在没有 Google 身份验证配置的情况下进行发布测试,令我惊讶的是,该应用程序在 Kubernetes 中具有健康状态,并且可以在 URL 上使用正确使用 https。当我在项目的 Startup.cs 中再次包含 Google 身份验证时,我的问题又出现在 Kubernetes 容器中,并且在访问 URL 时,我得到的返回结果是 502。
以下是我如何配置 Google 身份验证: 在 Startup.cs 上
配置服务方法:
public void ConfigureServices(IServiceCollection services)
{
//Auth config google
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddCookie()
.AddGoogle(options =>
{
options.ClientId = "{my_ClientId}";
options.ClientSecret = "{my_ClientSecret}";
});
...
}
配置方法:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/PaginaNaoEncontrada");
app.UseHsts();
}
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 404)
{
context.Request.Path = "/Home/PaginaNaoEncontrada";
await next();
}
});
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = o => { o.Context.Response.Headers.Append("Cache-Control", $"public, max-age=10800"); }
});
app.UseUnobtrusiveAjax();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication(); //Important
}
在我的 HomeController.cs 中(第一次访问应用程序时我的第一个请求命中,并且我验证用户是否已通过身份验证)控制器上方的 [Authorize] 注释对于我在启动中添加的工作 .cs 是绝对必要的:
[Authorize]
public class HomeController : Controller
{ ...}
我对家庭指数的行动:
[HttpGet]
return View();
通过 Index 调用 LoginGoogle:
public ActionResult LoginGoogle(){
return Challenge(new AuthenticationProperties { RedirectUri = "/" }, "Google");}
为了发布到 Kubernetes,我有以下文件(我突出显示其中三个,因为我认为该站点最重要的设置都在其中):
我的部署看起来像这样:
apiVersion: apps/v1
我的 Ingress 看起来像这样:
apiVersion: networking.k8s.io/v1
我的服务如下所示:
apiVersion: v1
最近我对 Kubernetes 的 .yaml 文件进行了更改,我开始从服务接收更多日志,类似于如果我运行不带参数的“Docker run”命令来使用本地证书,我在本地收到的日志:最新容器日志: https://drive.google.com/file/d/1VcmiBe0LBuMr5B0VC5YivrvZdygZtEf5/view?usp=drive_link
在进行这些更改之前(主要在部署文件中),我在日志中收到以下返回: 以前的日志: https: //drive.google.com/file/d/16NoN1fhhmoGk2bZRWTY0oxqFBY3xH4Kj/view ?usp=drive_link
上面所示的日志下方只是有关 ResponseCoockies 的信息的无限循环,并且有关 https 端口的信息不会重复,直到进行新的部署为止。
当我们在配置了 Google 身份验证的情况下发布时,访问 URL 时服务如何响应:https: //drive.google.com/file/d/1jDCmZNFPvzRvnq2VeOr7yC79A9Cba1rf/view ?usp=drive_link
我的问题是,我当前是否正在配置 Kubernetes,或者是否缺少信任证书的某些内容?当我从应用程序中删除 Google 身份验证配置时,为什么部署会正常进行?(我删除了启动配置和控制器注释)
请务必注意,我的 OAuth 客户端 ID 凭据是正确的,因为我能够通过添加授权的 https 本地主机 URL 来进行测试,因此这也不会成为问题。我将在 Kubernetes 中配置的 URL 添加到授权使用客户端 ID OAuth 的 URL 列表中,如下所示: https: //drive.google.com/file/d/1Hzi74jJ6sZ7za5D3rFZcyDQRaIoW4jOS/view ?usp=drive_link
其他信息。
当我在没有 Google 身份验证配置的情况下发布应用程序时的屏幕截图,它保持正常运行,并且证书似乎已链接到 URL 并且安全:
https://drive.google.com/file/d/1RLocACa-TaCsmZo1S74sQoKrzvFgcfyx/view?usp=drive_link
使用 Ingress.yaml 进行部署时,它会在基础设施中创建负载平衡,并自动配置链接到静态 IP 的前端端点:
https://drive.google.com/file/d/1f1LyIzcDqUbEUEpPTh6VQqdwyshMeUVA/view?usp=drive_link
我们使用AWS服务来购买和托管域名,因此当访问我配置的URL时,我的DNS将解析为我的前端的IP,我配置了一个“记录名称”以重定向到该IP。这已经对其他应用程序完成了,并且有效,甚至当我们在没有身份验证的情况下发布此应用程序时它也有效......
以下是我在AWS托管区域中进行的注册: https://drive.google.com/file/d/1y8BIeK7RYywP95jPzpCGYkgZ7Lv-w7KG/view ?usp=drive_link
以及由 Google 提供的证书的详细信息,并且由于我对 IP 所做的映射,只有在与 AWS 建立通信时该证书才变为“活动”,如上所述。 https://drive.google.com/file/d/1Y9wLH_DDX-93iMY5eNwBN0VcDFbId5I1/view?usp=drive_link
预先感谢您的帮助
我们找到了上述问题的解决方案。基本上,Kubernetes 中的容器需要,除了运行状况检查端点之外,应用程序的基本 url 也已启动,也就是说,我无法尝试将 [Authorize] 注释直接添加到我的 HomeController 中,因为它是应用程序显示的第一个。我定义应用程序的“默认”端点如下:
然而,HomeController 完全被 [Authorize] 覆盖,并且该应用程序在 kubernetes 后端被认为不健康。因此,解决关键问题的是创建一个登录屏幕(不应用[授权])来调用Google的登录并更改其默认端点:
因此后端变得很健康,应用程序启动,首先调用登录屏幕,然后单击“使用 Google 登录”,我们称之为 Google 的 OAuth 2.0,这是另一个问题...... 应用程序使用 HTTP 重定向到 OAuth,但我们需要更正此问题,使其重定向到 HTTPS。我们尝试了所有建议的解决方案,但在我们的案例中有效的是:
我们用作基础的 Microsoft 文档是:https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer ?view=aspnetcore-6.0 但是这个文档。这让我们感到困惑,我们尝试了所有建议,但在我们的案例中没有任何效果......直到 KnownNetworks 和 KnownProxies 的清除设置使我们的应用程序最终使用我们的 HTTPPS 重定向。