【问题标题】:Microsoft Identity Web: Change Redirect UriMicrosoft Identity Web:更改重定向 Uri
【发布时间】:2021-03-16 11:41:47
【问题描述】:

我正在使用 .net 5,Identity Web Ui 来访问 Microsoft Graph。我可以在哪里配置我的重定向 URI?

我需要指定完整的 Uri,因为从 callbackUri 生成的 Uri 不正确,因为它位于具有 SSL 卸载功能的负载均衡器后面。

这是我当前的 ConfigureServices 部分

    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
            .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
            .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
            .AddInMemoryTokenCaches();

【问题讨论】:

  • 你的意思是要在App注册端配置重定向url:docs.microsoft.com/en-us/azure/active-directory/develop/…
  • @AllenWu 我需要配置我的应用程序作为回调 url 发送的 URL,以便它与注册中的匹配。
  • 你做到了吗?
  • @david-ao 否,已启用从负载平​​衡器到 Web 服务器的 SSL。无论如何,这恰好是我的生产配置。还是想知道答案。
  • 我在一个类似的问题上苦苦挣扎了三天,我今天在工作中成功了,我要发布一个答案

标签: c# azure-active-directory microsoft-graph-api msal microsoft-identity-web


【解决方案1】:

我遇到了一个类似的问题,一个只暴露在前门后面的 WebApp,这个 WebApp 必须调用一个自定义的下游 WebApi。

在我的 localhost 开发机器上运行的服务配置:

// AzureAdB2C
        services
            .AddMicrosoftIdentityWebAppAuthentication(
                Configuration,
                "AzureAdB2C", subscribeToOpenIdConnectMiddlewareDiagnosticsEvents: true)
            .EnableTokenAcquisitionToCallDownstreamApi(p =>
                {
                    p.RedirectUri = redUri; // NOT WORKING, WHY?
                    p.EnablePiiLogging = true;
                },
                [... an array with my needed scopes]
            )
            .AddInMemoryTokenCaches();

我尝试了 AddDownstreamWebApi,但没有成功,所以我只是使用 ITokenAcquisition 获取所需的令牌并将其添加到 HttpClient 以发出我的请求。

然后我需要 AzureAd/B2C 登录重定向到带有前门 url 的 uri: https://example.org/signin-oidc 事情发生了。我是这样解决的:

首先,您必须将此 url 添加到您在 azure 门户中的应用注册中,非常重要的是区分大小写,它关心尾部斜杠,我怀疑有许多 url 指向同一个控制器,并且它们的顺序有一些影响,我只是删除了所有内容并保持最低限度。

然后在configure services方法中:

services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
        {
            options.SaveTokens = true; // this saves the token for the downstream api
            options.Events = new OpenIdConnectEvents
            {
                OnRedirectToIdentityProvider = async ctxt =>
                {
                    // Invoked before redirecting to the identity provider to authenticate. This can be used to set ProtocolMessage.State
                    // that will be persisted through the authentication process. The ProtocolMessage can also be used to add or customize
                    // parameters sent to the identity provider.
                    ctxt.ProtocolMessage.RedirectUri = "https://example.org/signin-oidc";
                    await Task.Yield();
                }
            };
        });

重定向成功了,但我在受保护页面和 AzureB2C 登录之间进入了一个循环。

在成功登录并正确重定向到 signin-oidc 控制器(由 Identity.Web 包创建)后,我再次被正确重定向到启动所有这些授权的页面,但在那里它没有找到授权。所以我也添加/修改了这个:

services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
            options.Secure = CookieSecurePolicy.Always;
        });

有了这个授权工作,但我无法让令牌调用下游 API,在此重定向事情 ITokenAcquisition 工作之前,但现在当尝试获取令牌时它会引发异常。

所以在我的控制器/服务中获取我修改和使用的令牌:

var accessToken = await _contextAccessor.HttpContext
                .GetTokenAsync(OpenIdConnectDefaults.AuthenticationScheme, "access_token");

所以现在我使用令牌将它添加到我的 HttpRequestMessage 中,如下所示:

request.Headers.Add("Authorization", $"Bearer {accessToken}");

我在 StackOverflow 和 microsoft docs 上生活了 3 天,我不确定这是否都是“推荐”的,但这对我有用。

【讨论】:

  • 太棒了。我能够启用 SSL 并进行我的工作,但我会接受这是解决此问题的正确方法。
【解决方案2】:

我在 3 天内遇到了类似的问题。下面的代码帮助我摆脱了这个问题。

string[] initialScopes = Configuration.GetValue<string>("CallApi:ScopeForAccessToken")?.Split(' ');

        services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
            .AddInMemoryTokenCaches();
        services.AddControllers();
        services.AddRazorPages().AddMvcOptions(options =>
        {
            var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser().Build();
            options.Filters.Add(new AuthorizeFilter(policy));

        }).AddMicrosoftIdentityUI();
        services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
        {
            options.SaveTokens = true; // this saves the token for the downstream api
            options.Events = new OpenIdConnectEvents
            {
                OnRedirectToIdentityProvider = async ctxt =>
                {

                    ctxt.ProtocolMessage.RedirectUri = "https://example.org/signin-oidc";
                    await Task.Yield();
                }
            };
        });

【讨论】:

    【解决方案3】:

    我在 Google Cloud Run 下运行 asp.net 应用程序时遇到了同样的问题,它终止了 TLS 连接。我收到了错误: AADSTS50011:请求中指定的回复 URL 与为应用程序配置的回复 URL 不匹配。

    使用 fiddler,我检查了对 login.microsoftonline.com 的请求,发现查询参数 redirect_uri 与我在 Azure 应用程序中配置的 url 完全匹配,只是它启动的是 http 而不是 https。

    我最初尝试了涉及处理 OpenIdConnectEvents 事件和更新重定向 uri 的其他答案。这修复了对 login.microsoftonline.com 的调用中的 redirect_url 参数,然后它一直有效,直到我添加到图形 api 中。然后我发现我网站的 signin-oidc 页面会给出关于重定向 uri 不匹配的错误。这将导致它进入我的网站和 login.microsoftonline.com 之间的循环,反复尝试进行身份验证,直到最终我登录失败。

    在进一步的研究中,ASP.net 提供了正确处理这种情况的中间件。您的 SSL 负载均衡器应将带有值 HTTPS 的标准标头 X-Forwarded-Proto 添加到请求中。它还应该发送带有原始 IP 地址的 X-Forwarded-For 标头,这可能对调试、geoip 等有用。

    在您的 ASP.net 应用程序中,配置中间件:

    services.Configure<ForwardedHeadersOptions>(options =>
     {
       options.ForwardedHeaders =
           ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
       options.KnownNetworks.Clear();
       options.KnownProxies.Clear();
     });
    

    然后启用中间件:

    app.UseForwardedHeaders();
    

    重要的是,您必须在调用依赖它的 app.UseAuthentication/app.UseAuthorization 之前包含它。

    来源:https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-5.0

    如果您的负载均衡器没有添加 X-Forwarded-Proto 标头并且无法配置为这样做,那么上面的文档概述了其他选项。

    【讨论】:

    • 非常有趣,我得检查一下我的标题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多