首页 > 解决方案 > 在 azure kubernetes 服务中使用 oidc 身份验证在 azure 应用程序网关和 Identity Server 4 中运行 aspnet core 3.1 MVC 应用程序

问题描述

我在 azure 的 kubernetes 服务中运行 aspnet core 3.1 MVC 应用程序。AKS 位于应用程序网关后面。Azure 应用程序网关入口控制器 pod 在 AKS 中运行,我的部署、服务和入口配置如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  name: imagename
  namespace: namespacename
spec:
  replicas: 1
  selector:
    matchLabels:
      app: imagename
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: imagename
    spec:
      containers:
      - name: imagename
        image: acrname.azurecr.io/imagename:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 80
          name: http
        readinessProbe:
          httpGet:
            path: /probes  
            port: 80
          periodSeconds: 30
          timeoutSeconds: 3
        env:
        - name: ASPNETCORE_ENVIRONMENT
          value: "dev"
        resources:
          requests:
            cpu: 150m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 500Mi
status: {}
---
apiVersion: v1
kind: Service
metadata:
  name: imagename
  namespace: namespacename
spec:
  selector:
    app: imagename
  ports:
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: imagename
  namespace: namespacename
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/backend-path-prefix: "/"
    appgw.ingress.kubernetes.io/appgw-ssl-certificate: certificatename
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
  - host: exampledomain.com.br
    http:
      paths:
      - path: /pathapp/*
        backend:
          serviceName: imagename
          servicePort: 80

身份服务器 pod 已在 AKS 中运行,并且身份验证过程适用于承载方案。

对于 Cookies 方案,应用程序能够通过身份服务器使用 azure AD 进行身份验证,但在应用程序 pod 的 /signin-oidc 端点的重定向上,我遇到了 404 错误。该应用程序的 pod 日志显示:

执行请求时发生未处理的异常。System.Exception:处理远程登录时遇到错误。---> System.Exception:关联失败。--- 内部异常堆栈跟踪结束 ---

配置 ASP.NET Core 以使用代理服务器和负载平衡器中的说明已在应用程序中实现。

应用程序中重定向到 /signin-oidc 的完整 pod 如下图所示:

关联失败

这是我的启动课:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuracao = configuration;
        }

        public IConfiguration Configuracao { get; }

        public void ConfigureServices(IServiceCollection servicos)
        {
            servicos.AddApplicationInsightsTelemetry(Configuracao.GetValue<string>("ApplicationInsights:InstrumentationKey"));
            //servicos.AddAICustomizado(Configuracao);

            servicos.AddControllersWithViews();
            servicos.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                    ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
            });
            servicos.AddRazorPages().AddRazorRuntimeCompilation();
            //servicos.AddMvcCustomizado();

            servicos.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
                            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
                            .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
                            {
                                options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                                options.ResponseType = OpenIdConnectResponseType.Code;
                                options.Authority = Configuracao.GetValue<string>("Autenticacao:IdentityServer:UrlBase");
                                options.ClientId = "clientimplicit";
                                options.ResponseType = "id_token token";
                                options.SaveTokens = true;
                                options.Scope.Clear();
                                options.Scope.Add("openid");
                                options.Scope.Add("Scope2");
                                options.Scope.Add("Scope3");
                                options.UseTokenLifetime = true;
                                options.RequireHttpsMetadata = false;
                                options.Events.OnRedirectToIdentityProvider = async n =>
                                {
                                    n.ProtocolMessage.RedirectUri = $"{Configuracao.GetValue<string>("Autenticacao:RedirectUri:UrlBase")}signin-oidc";
                                    await Task.FromResult(0);
                                };
                                options.Events.OnRedirectToIdentityProviderForSignOut = async n =>
                                {
                                    n.ProtocolMessage.PostLogoutRedirectUri = $"{Configuracao.GetValue<string>("Autenticacao:RedirectUri:UrlBase")}signout-callback-oidc";
                                    await Task.FromResult(0);
                                };
                            });

            servicos.AddAuthorization();
            //servicos.AddAutenticacaoCustomizada(Configuracao);
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.Use((context, next) =>
            {
                context.Request.Scheme = "https";
                return next();
            });

            app.UseForwardedHeaders();

            if (env.EnvironmentName.Equals("prd", System.StringComparison.CurrentCultureIgnoreCase))
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            //app.UseHttpsRedirection();

            app.UseStaticFiles();

            app.UseRouting();

            app.UseAutenticacaoCustomizada();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=cliente}/{action=index}/");
            });
            //app.UseMvcCustomizado(env);
        }
    }

有人可以借给我一些有关 Correlation failed 错误的帮助吗?

标签: asp.net-coreidentityserver4openid-connectapi-gatewayazure-aks

解决方案


因此,经过一番努力使其工作后,我找到了解决方案。

整个问题与与我的 Azure 应用程序网关绑定的证书的 de SSL 证书链有关。

有人以错误的方式导出它,而不包括证书路径:

在此处输入图像描述

上图是在 Windows Server 上导出证书时需要勾选的复选框。

要检查您的网关上的证书链是否完整,当您在 Windows 中且未安装 openssl 时,在 git bash 中运行以下命令:

openssl s_client -showcerts https://domainbindedwithgateway.com.br:443

用链完成重新绑定正确的证书后,错误消失。

有关 SSL 证书和负载均衡器等的良好参考,请参阅:

[Azure] 应用程序网关证书问题


推荐阅读