我一直在尝试让一个简单的自托管 OWIN WebAPI 在旧版 Windows 服务应用程序中运行。我让它正常工作,直到我尝试使用 Microsoft.Identity.Web.OWIN 添加 Microsoft Entra ID 身份验证。
不幸的是,我面临着一个未记录的错误,而且谷歌搜索甚至没有提到任何相关内容,所以我希望这里有人遇到过类似的问题。
我遇到的问题是在我的启动中:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
// Exception is thrown on next line
OwinTokenAcquirerFactory factory = TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>();
app.AddMicrosoftIdentityWebApi(factory);
factory.Build();
}
}
TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>();
正在创建 System.NullReference 异常。查看堆栈跟踪,当它尝试访问 DefineConfiguration(IConfigurationBuilder builder)
时,它挂在 OwinTokenAcquirerFactory
的 HttpContext.Current.Request.PhysicalApplicationPath
方法重写上:
protected override string DefineConfiguration(IConfigurationBuilder builder)
{
_ = builder.AddInMemoryCollection(new Dictionary<string, string>()
{
["AzureAd:Instance"] = EnsureTrailingSlash(ConfigurationManager.AppSettings["ida:Instance"] ?? ConfigurationManager.AppSettings["ida:AADInstance"] ?? "https://login.microsoftonline.com/"),
["AzureAd:ClientId"] = ConfigurationManager.AppSettings["ida:ClientId"],
["AzureAd:TenantId"] = ConfigurationManager.AppSettings["ida:Tenant"] ?? ConfigurationManager.AppSettings["ida:TenantId"],
["AzureAd:Audience"] = ConfigurationManager.AppSettings["ida:Audience"],
["AzureAd:ClientSecret"] = ConfigurationManager.AppSettings["ida:ClientSecret"],
["AzureAd:SignedOutCallbackPath"] = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"],
["AzureAd:RedirectUri"] = ConfigurationManager.AppSettings["ida:RedirectUri"],
});
return HttpContext.Current.Request.PhysicalApplicationPath; //NullReference exception here
}
注意,启动代码是在服务初始化阶段调用的,所以这里肯定没有HttpContext。我很惊讶这甚至可以在任何 OWIN Startup 方法中工作,所以我对发生的事情感到非常困惑。以下是有关如何使用 OWIN 和 AzureAD 的所有标准文档。
我尝试添加一个模拟 HttpContext,它让我在调用堆栈中更进一步,但尝试从中获取
Request.PhysicalApplicationPath
仍然失败。我的 OWIN 自托管设置中是否缺少某些内容?
谢谢大家,任何帮助将不胜感激
我和同一个图书馆发生过争执。这不太好。 我怀疑 HttpContext.Current 不可用,因为如果您运行纯基于 OWIN 的应用程序,则不会依赖于 system.web,并且实际上您的请求线程上不会有状态 HttpContext.Current 可用。 如果您运行的是 webforms 或 asp.net mvc(框架)应用程序,那么它就会运行,然后这将起作用。
您可以通过继承
AcquirerFactory
来创建自己的 OwinTokenAcquirerFactory
类来解决此问题。这将允许您重写 DefineConfiguration
方法并允许您避免 HttpContext.Current 调用。但是我不能保证在 OwinTokenAcquirerFactory
实现中不会有更多的 HttpContext.Current 调用。