问题描述
我有一个Service Fabric群集,该群集正在运行无法公开给Internet的服务(无状态ASP.Net Core)。对服务的请求通过API管理进行路由。
Incoming request ==> https://blah.trafficmanager.net/routeName
forwarded ==> https://10.0.4.6:[port]/routeName
这无需任何身份验证即可正常工作。我正在连接AAD身份验证,因为我们需要将其锁定到客户端注册(由于具有时间限制的海拔请求)。我已经将服务设置为使用AAD身份验证,并且在我的本地开发Service Fabric集群中运行时,可以使用以下参数正常工作(即,提示登录,根据角色对路由进行选通):
"AzureAd:ClientId": "[client id]","AzureAd:Domain": "[tenant].onmicrosoft.com","AzureAd:Instance": "https://login.microsoftonline.com/","AzureAd:SignedOutCallbackPath": "/signout-callback-oidc","AzureAd:CallbackPath": "/signin-oidc","AzureAd:TenantId": "[tenant id]",
当我部署它并尝试通过https://blah.trafficmanager.net/routeName,重定向https://10.0.4.6:44321/signin-oidc进行访问时,最终得到:
这是我的startup.cs代码:
/// <summary>
/// Configure services
/// </summary>
/// <param name="services">Service collection</param>
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
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.Unspecified;
// Handling SameSite cookie according to https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
options.HandleSameSiteCookieCompatibility();
});
// Sign-in users with the Microsoft identity platform
services.AddMicrosoftWebAppAuthentication(this.Configuration);
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.All;
options.KNownProxies.Add(IPAddress.Parse("10.0.4.6"));
});
// services.AddControllers();
services.AddControllers(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new Authorizefilter(policy));
});
}
/// <summary>
/// Configure app
/// </summary>
/// <param name="app">App builder</param>
/// <param name="env">Environment</param>
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseForwardedHeaders();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
我想知道是否可以做些什么才能使群集节点上的此服务能够对通过APIM传入的请求进行身份验证。
谢谢!
解决方法
我可以使用以下方法覆盖回复网址:
services.Configure<OpenIdConnectOptions>(
OpenIdConnectDefaults.AuthenticationScheme,options =>
{
var redirectToIdpHandler = options.Events.OnRedirectToIdentityProvider;
options.Events.OnRedirectToIdentityProvider = async context =>
{
// Call what Microsoft.Identity.Web is doing
await redirectToIdpHandler(context);
// Override the redirect URI so that auth works behind APIM
context.ProtocolMessage.RedirectUri = this.Configuration["AzureAd:RedirectUri"];
};
});
然后我遇到了身份验证问题,因为它会循环很多次并最终给出错误标志。我发现这是因为我的回复网址是主站点,而不是signin-oidc。当我添加带有APIM的signin-oidc作为回复URL时,APIM失败,因为没有使用该名称的路由。我创建了一个新API,将signin-oidc转发到后端的同一路由。
现在,从AAD回来的回复在signin-oidc上命中了我的APIM,并转发到了背面。这样就可以完成身份验证。