繁体   English   中英

在 Asp.NET Core Azure AD 身份验证中配置重定向 URI

[英]Configure redirect URI in Asp.NET Core Azure AD authentication

如何告诉我的应用使用我提供的主机生成重定向 URI? ( foobar.com )

语境:

我有从最近的(VS 16.7.5)模板生成的服务器端 Blazor Web 应用程序,具有 Azure AD(单租户、工作和学校)身份验证。

我使用<PackageReference Include="Microsoft.AspNetCore.Authentication.AzureAD.UI" Version="3.1.8" />

我已经在 Az Portal 等处配置了接受的重定向 URL,并且可以在本地运行我的应用程序时使用 Azure AD 登录。

流动

重定向 URI 在重定向到 Azure AD 站点时在查询参数中发送,它指向实际上是foobar.azurewebsites.net的网站主机。

如何告诉我的应用使用我提供的主机生成重定向 URI? ( foobar.com )

我发现的唯一解决方案与以前的 ASP.NET 有关。

<add key="ida:RedirectUri" value="https://localhost:44326/" />

在我的情况下,这不起作用。

作为一种解决方法,我添加了一个中间件,用于替换发送到 Azure AD 的回调 URL 中的redirect_uri参数。

public class ResponseInspectMiddleware
{
    private readonly RequestDelegate _next;
    private readonly AzureADSettings _azureAdSettings;

    public ResponseInspectMiddleware(RequestDelegate next, AzureADSettings azureAdSettings)
    {
        _next = next;
        _azureAdSettings = azureAdSettings;
    }

    public async Task Invoke(HttpContext context)
    {
        await _next(context);

        var headers = context.Response.Headers;
        const string LOCATION_HEADER = "location", REDIRECT_URI_PARAM = "redirect_uri";

        if (context.Response.StatusCode == 302
            && headers.ContainsKey(LOCATION_HEADER)
            && Uri.TryCreate(headers[HeaderNames.Location], UriKind.RelativeOrAbsolute, out var locationHeader))
        {
            Url locationUrl = locationHeader;

            if (locationUrl.ToString().StartsWith(_azureAdSettings.Instance)
                && locationUrl.QueryParams.ContainsKey(REDIRECT_URI_PARAM))
            {
                // Update redirect_url query param

                // Make new redirect url
                var callbackHost = _azureAdSettings?.CallbackHost ?? throw new ArgumentNullException($"{_azureAdSettings.CallbackHost} is not set.");
                var callbackPath = _azureAdSettings?.CallbackPath ?? throw new ArgumentNullException($"{_azureAdSettings.CallbackPath} is not set.");
                Url newRedirectUrl = callbackHost + callbackPath;

                locationUrl.SetQueryParam(REDIRECT_URI_PARAM, newRedirectUrl, isEncoded: false);

                // Swap location headers
                headers.Remove(LOCATION_HEADER);
                headers.Add(LOCATION_HEADER, new StringValues(locationUrl.ToString()));
            }
        }
    }
}

当 Web 应用位于 Azure 前门或应用网关之后,我们需要将 /authorize 请求中的 redirect_uri 配置为网关/前门的地址。

在下面的代码中,我们覆盖“OnRedirectToIdentityProvider”事件并注入前门/网关的地址。 当我尝试这个时,我只是对地址进行了硬编码,但理想情况下,您将从 Front Door 或 App Gateway 注入请求的标头中提取它。

这是我在尝试对在 Azure 应用服务上运行的 Blazor 服务器应用 (.net 5) 进行身份验证时使用的代码,受 Azure AD 保护,在 Azure Front Door 后面运行。

public void ConfigureServices(IServiceCollection services)
{
    // ... existing code

    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
                .EnableTokenAcquisitionToCallDownstreamApi(new[] { "User.Read" })
                .AddInMemoryTokenCaches();

    services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
    {
        options.Events = new OpenIdConnectEvents
        {
            OnRedirectToIdentityProvider = (context) =>
            {   
                // Override the redirect_uri
                //  Ideally extract this from config 
                //  Or context.Request.Headers["X-Forwarded-Host"]
                //  see: https://docs.microsoft.com/en-us/azure/frontdoor/front-door-http-headers-protocol#front-door-to-backend

                context.ProtocolMessage.RedirectUri 
                    = "https://YOUR-FRONT-DOOR-or-APP-GATEWAY/signin-oidc";
                return Task.FromResult(0);
            }
        };
    });

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

    // ... existing code
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ... existing code
    
    // Don't forget to add this ...
    app.UseForwardedHeaders();
    
    // ... existing code
}

当代码工作时,“redirect_uri”参数应指向您的前门/网关,如此处所示。

OAuth 流程

希望有帮助。 ❤️

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM