.net core 在使用Azure AD身份验证和oidc以及中间件的web应用中指定自定义重定向uri

.net core 在使用Azure AD身份验证和oidc以及中间件的web应用中指定自定义重定向uri,.net-core,azure-active-directory,openid-connect,service-fabric-stateless,.net Core,Azure Active Directory,Openid Connect,Service Fabric Stateless,我正在尝试使用Azure AD对应用程序进行身份验证。在localhost中一切正常,它会重定向到Azure AD,在那里我输入详细信息进行身份验证,然后它会发回允许查看资源的令牌。 在AspNetCore 3.1应用程序中,通过Microsoft.AspNetCore.Authentication.AzureAD.UI 3.1.10在后台管理所有内容 我的应用程序运行在http://localhost:5000 我可以在Azure AD上为该应用程序配置redirectUri/replyUri

我正在尝试使用Azure AD对应用程序进行身份验证。在localhost中一切正常,它会重定向到Azure AD,在那里我输入详细信息进行身份验证,然后它会发回允许查看资源的令牌。 在AspNetCore 3.1应用程序中,通过Microsoft.AspNetCore.Authentication.AzureAD.UI 3.1.10在后台管理所有内容

我的应用程序运行在http://localhost:5000 我可以在Azure AD上为该应用程序配置redirectUri/replyUri以支持此url。一切都好

当我的应用程序在服务结构群集中运行时,问题出现在不同的环境中。 我能看出问题所在

AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application
当我检查url时,我可以看到
redirect\u uri
有这样的url
http://12.12.12.12/signin-oidc

这里的问题是双重的。首先,我不知道集群将分配哪个IP。其次,它是http,而不是https,Azure AD不支持它

幸运的是,我的应用程序有一个带有反向代理的外部Url,我可以用来访问。类似于
https://myservicefabriccluster.com/MyApp

我可以在我的应用程序和Azure AD中将该Url配置为我的
重定向uri
,但我不知道如何这样做

我的代码是这样的:

services
    .AddAuthentication(AzureADDefaults.AuthenticationScheme)
    .AddAzureAD(options => Configuration.Bind("AzureAd", options));
"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "ClientId": "76245c66-354e-4a94-b34d-...",
  "TenantId": "59c56bd4-ce18-466a-b515-..."
  "IsCustomRedirectUriRequired": true,
  "CustomRedirectUri": "https://platform-cluster-development01.cubictelecom.com:19008/Scheduler/WebApi/signin-oidc"
},
我在那里绑定我的设置

"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "ClientId": "76245c66-354e-4a94-b34d-...",
  "TenantId": "59c56bd4-ce18-466a-b515-..."
},
我可以看到
AzureADOptions
支持一些其他参数,例如
Domain
(不需要)或
CallbackPath
(默认情况下可以是
/signin-oidc
),但是没有任何类似于ReplyUrl或RedirectUri的参数,我可以指定一个绝对URL作为回调

我发现了一些没有答案的类似问题。其他人则提出了一些技巧,比如在重定向到Azure AD之前重写该参数的中间件


当然,必须有一个更简单的方法来处理这个问题,我认为这并不奇怪。有什么帮助吗?

看看这个,您应该将公共URL配置为重定向URI,该值如下:

看起来上面的库不容易支持这一点,并强制重定向URI基于代码的HTTP侦听URL。作为解决此问题的一部分,值得考虑如何编写代码:

这行代码表示您的应用程序仅限于使用Azure广告:

- services.AddAzureAD
这一行代码将确保您的代码同时适用于AzureAD和满足Open Id Connect标准的任何其他授权服务器:

- services.AddOpenIdConnect
后一个选项还有一个Events类,其中包含一个常用的操作,您可以使用该操作覆盖回调路径并提供完整的重定向URI


Azure AD端点基于标准,因此您不必严格使用AzureAD特定的库。出于兴趣,我有一个使用类似这样的中性库的解决方案,因此我知道这种技术是有效的。

使用自定义值覆盖
redirect\u uri
参数的解决方案是使用OpenIdConnect库中可用的事件。这个库应该是可用的,因为它是Microsoft.AspNetCore.Authentication.AzureAD.UI的依赖项,所以这是我的解决方案,除了AzureADOptions的标准属性外,它还添加了一个标志来确定是否必须覆盖重定向uri以及一个值。我希望这是不言自明的

services
    .AddAuthentication(AzureADDefaults.AuthenticationScheme)
    .AddAzureAD(options => configuration.Bind("AzureAd", options));

var isCustomRedirectUriRequired = configuration.GetValue<bool>("AzureAd:IsCustomRedirectUriRequired");
if (isCustomRedirectUriRequired)
{
    services
        .Configure<OpenIdConnectOptions>(
            AzureADDefaults.OpenIdScheme,
            options =>
            {
                options.Events =
                    new OpenIdConnectEvents
                    {
                        OnRedirectToIdentityProvider = async ctx =>
                        {
                            ctx.ProtocolMessage.RedirectUri =
                                configuration.GetValue<string>("AzureAd:CustomRedirectUri");
                            await Task.Yield();
                        }
                    };
            });
}

services
    .AddAuthorization(
        options =>
        {
            options.AddPolicy(
                PolicyConstants.DashboardPolicy,
                builder =>
                {
                    builder
                        .AddAuthenticationSchemes(AzureADDefaults.AuthenticationScheme)
                        .RequireAuthenticatedUser();
                });
        });

请注意,
IsCustomRedirectUriRequired
CustomRedirectUri
是我的自定义属性,在重定向到身份提供程序(即Azure AD)时,我会显式读取这些属性以覆盖(或不覆盖)重定向uri查询参数。

谢谢,您为我指明了正确的方向。不过,该库并没有被弃用。事实上,有一个新版本的.NET5.0,但你是对的,这个库有点受限,我仍然可以使用OpenIdConnect更标准的库来访问事件。我很快就会发布解决方案。我在Microsoft.Identity.Web上尝试了相同的方法,它的工作方式也是一样的。