我的Web应用程序无法使用OpenIdConnect进行身份验证。目前,我在OnRemoteFailure
上看到“关联失败”错误。
上下文:
启动:
public void ConfigureServices(IServiceCollection services)
{
(...)
services.AddMvc();
(...)
services.AddAuthorization();
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(o =>
{
o.ClientId = clientId;
o.Authority = $"https://login.microsoftonline.com/{tenantId}/{signinPolicy}/v2.0";
o.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.SaveTokens = true;
o.Events = new OpenIdConnectEvents
{
OnTokenValidated = async context =>
{
(...)
},
OnRedirectToIdentityProvider = async context =>
{
if (context.Request.Headers.TryGetValue("X-Forwarded-Prefix", out var prefix) && prefix.Count > 0 &&
context.Request.Headers.TryGetValue("X-Forwarded-Host", out var hostValues) && hostValues.Count > 0 &&
context.Request.Headers.TryGetValue("X-Forwarded-Proto", out var protoValues) && protoValues.Count > 0)
{
// Use external URL and path
string redirectUri = $"{protoValues.First()}://{hostValues.First()}{prefix.First()}{context.Options.CallbackPath}";
context.ProtocolMessage.RedirectUri = redirectUri;
}
},
OnTokenResponseReceived = async context =>
{
},
OnAuthenticationFailed = async context =>
{
},
OnRemoteFailure = async context =>
{
}
};
o.ConfigurationManager = new PolicyConfigurationManager($"https://login.microsoftonline.com/{tenantId}/{signinPolicy}/v2.0",
new[] { signinPolicy });
});
(...)
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseStaticFiles();
app.UseAuthentication();
app.Use(async (context, next) =>
{
if (context.Request.Headers.TryGetValue("X-Forwarded-Prefix", out var prefix) && prefix.Count() > 0)
{
context.Request.PathBase = prefix.First();
}
await next.Invoke();
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
控制器:
public class AccountController : Controller
{
[HttpGet]
public IActionResult SignIn()
{
if (Request.Headers.TryGetValue("X-Forwarded-Prefix", out var prefix) && prefix.Count() > 0)
{
return Challenge(new AuthenticationProperties { RedirectUri = prefix.First() }, OpenIdConnectDefaults.AuthenticationScheme);
}
else
{
(...)
}
}
(...)
}
事件OnTokenValidated
从未触发。
关于反向代理,它基本上将https://internal_url:port/internal_path映射到https://external_url/external_path。
我检查了请求,这是访问的GET:
https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize?p={signinPolicy}&client_id={clientId}&redirect_uri=https%3A%2F%2F{external_host}%2F{external_path}%2Fsignin-oidc&response_type=id_token&scope=openid%20profile&response_mode=form_post&nonce=(...)&x-client-SKU=ID_NET&x-client-ver=2.1.4.0
成功,然后POST请求失败:
https://{external_url}/{external_path}/signin-oidc
此POST包含表单数据id_token
和state
。
在B2C中配置的重定向URL为https://{external_url}/{external_path}/signin-oidc
。我也尝试过https://{external_url}/{external_path}
,但效果不佳。
我尝试使用转发标题,但没有帮助。
谁能指出我所缺少的东西?
谢谢!
答案 0 :(得分:5)
我发现了问题。问题出在中间件的顺序上。身份验证中间件必须在PathBase上进行更改之后进行。 在我的情况下,不需要转发的标头。
遵循固定的Configure
方法。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.Use(async (context, next) =>
{
if (context.Request.Headers.TryGetValue("X-Forwarded-Prefix", out var prefix) && prefix.Count() > 0)
{
context.Request.PathBase = prefix.First();
}
await next.Invoke();
});
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}