[英]ASP.NET Core 3.1 Azure AD Authentication throws OptionsValidationException
[英]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”参数应指向您的前门/网关,如此处所示。
希望有帮助。 ❤️
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.