asp.net WebForms中的Azure AD身份验证在本地工作,但不在实时服务器上工作

vi4fp9gy  于 2023-06-07  发布在  .NET
关注(0)|答案(1)|浏览(148)

我有一些奇怪的错误时,试图在旧的遗留WebForms应用程序设置AD身份验证。我已经升级了解决方案以使用.NET Framework 4.8并安装了nuget包。
作为最后的手段,我尝试在VS 2022中创建一个新的.NET Framework 4.8 WebForms应用程序,并将其设置为使用AAD身份验证。现在,这在我的本地开发机器上完美地工作(我将响应URL指定为https://localhost:7308,分配的端口)。
但是,如果我把网站放在我的实时服务器上(运行IIS的Windows Server 2019),并将AAD的响应URL重新指向该服务器,我得到的就是这个错误:
异常类型:OpenIdConnectProtocolInvalidNonceException异常消息:IDX21323:RequireNonce为'[PII已隐藏。有关更多详细信息,请参见https://aka.ms/IdentityModel/PII.]'。OpenIdConnectProtocolValidationContext.Nonce为null,
这是我现在拥有的代码(我已经尝试过更改cookie设置)

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            CookieManager = new SystemWebCookieManager(),
            CookieSameSite = Microsoft.Owin.SameSiteMode.Lax,
            CookieHttpOnly = true,
            CookieSecure = CookieSecureOption.Never
        });

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = authority,
                PostLogoutRedirectUri = postLogoutRedirectUri,
                RequireHttpsMetadata = false,

                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthenticationFailed = (context) =>
                    {
                        return System.Threading.Tasks.Task.FromResult(0);
                    },

                    SecurityTokenValidated = (context) =>
                    {
                        string name = context.AuthenticationTicket.Identity.FindFirst("preferred_username").Value;
                        context.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Name, name, string.Empty));
                        return System.Threading.Tasks.Task.FromResult(0);
                    }
                }
            });

我还尝试将AuthenticationFailed设置为

AuthenticationFailed = (context) =>
                    {
                        if (context.Exception.Message.Contains("IDX21323"))
                        {
                            context.HandleResponse();
                            context.OwinContext.Authentication.Challenge();
                        }

                        return Task.FromResult(true);
                    },

但这只会让我陷入一个循环,在那里我一遍又一遍地得到AAD登录屏幕。
我有一个怀疑我们在实际环境中的设置是一个HAPRoxy,它负责将流量路由到我们拥有的各种Web服务器。它还处理SSL,因此所有到达我的实际IIS服务器的流量都是普通HTTP流量。但我不知道

  1. AAD身份验证可以在这样的设置中工作,或者
    1.我需要有一个实际的SSL证书设置在IIS机器上,以处理这一点
    我试着用谷歌搜索我的眼睛,但到目前为止,这是无济于事的,所以我把它放在SO社区的温暖手中。
    有人对此有什么想法吗?
f87krz0w

f87krz0w1#

我能够对Web窗体.NET 4.8进行身份验证,并且能够登录而没有任何问题。
确保已为部署的应用程序添加了重定向URI。

我的StartupAuth.cs

我在代码中发现的区别是CookieAuthenticationOptions(CookieManager,CookieSameSite,CookieHttpOnly,CookieSecure)没有设置。

using System;
using System.Configuration;
using System.Security.Claims;
using Microsoft.Owin.Extensions;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;

namespace WebApplication1
{
    public partial class Startup
    {
        private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
        private static string aadInstance = EnsureTrailingSlash(ConfigurationManager.AppSettings["ida:AADInstance"]);
        private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
        private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];

        string authority = aadInstance + tenantId + "/v2.0";

        public void ConfigureAuth(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,

                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        AuthenticationFailed = (context) =>
                        {
                            return System.Threading.Tasks.Task.FromResult(0);
                        },

                        SecurityTokenValidated = (context) =>
                        {
                            string name = context.AuthenticationTicket.Identity.FindFirst("preferred_username").Value;
                            context.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Name, name, string.Empty));
                            return System.Threading.Tasks.Task.FromResult(0);
                        }
                    }
                });

            // This makes any middleware defined above this line run before the Authorization rule is applied in web.config
            app.UseStageMarker(PipelineStage.Authenticate);
        }

        private static string EnsureTrailingSlash(string value)
        {
            if (value == null)
            {
                value = string.Empty;
            }

            if (!value.EndsWith("/", StringComparison.Ordinal))
            {
                return value + "/";
            }

            return value;
        }
    }
}

web.config中的AppSettings:

<appSettings>
    <add key="ida:ClientId" value="********" />
    <add key="ida:AADInstance" value="https://login.microsoftonline.com/" />
    <add key="ida:Domain" value="****.onmicrosoft.com" />
    <add key="ida:TenantId" value="********" />
    <add key="ida:PostLogoutRedirectUri" value="https://localhost:44305/signin-oidc" />
  </appSettings>

本地输出:

部署的Azure应用服务输出:

我需要有一个实际的SSL证书设置在IIS机器上,以处理这一点
请参阅globalsign的此文档以在IIS上安装SSL证书。

相关问题