我正在开发一个由单独的 API (.NET 7) 和前端 (NextJS / React) 组成的 Web 应用程序。简而言之:前端调用API来获取应该显示的信息。
认证和授权应该通过单点登录(SSO)。客户端有一个本地 ADFS 服务器 (Windows Server 2019)。到目前为止,我已经设法设置 ADFS 以与前端应用程序一起实际登录并获取 JSON Web 令牌。
为此我创建了一个应用程序组:
前端使用 NextAuth 通过 oAuth 2.0 / OpenID Connect 协议对用户进行身份验证,方法是自动重定向到用户使用其 AD 帐户登录的 ADFS 身份验证页面。这工作正常。
既然前端是安全的,我也想保护API。就我对 ADFS 的理解而言,前端在调用 API 时应使用 JWT 作为承载令牌,然后应使用 ADFS 验证令牌。所以我正在尝试设置 .NET API 和 ADFS 之间的连接。
当访问any 路由(也是匿名的!)时,API 的控制台是massively 垃圾邮件异常。事实上:它是一个 Stack Overflow 异常:
info: Microsoft.Hosting.Lifetime[0]
Content root path: /app
Stack overflow.
at System.Collections.Generic.Dictionary`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].FindValue(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey)
at System.Collections.Generic.Dictionary`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, Microsoft.Extensions.DependencyInjection, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryGetValue(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCacheKey, System.__Canon ByRef)
at DynamicClass.ResolveService(ILEmitResolverBuilderRuntimeContext, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(System.Type, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.IServiceProvider)
at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.GetAuthenticationService(Microsoft.AspNetCore.Http.HttpContext)
at Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.AuthenticateAsync(Microsoft.AspNetCore.Http.HttpContext, System.String)
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1+<HandleAuthenticateAsync>d__13[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1+<HandleAuthenticateAsync>d__13[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Authentication, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<HandleAuthenticateAsync>d__13<System.__Canon> ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1+<HandleAuthenticateAsync>d__13[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Authentication, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<HandleAuthenticateAsync>d__13<System.__Canon> ByRef)
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1+<AuthenticateAsync>d__48[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
这一直持续到应用程序最终崩溃。
OpenID Connect / oAuth 2.0 和 ADFS 对我来说绝对是新概念。我确实了解基础知识,但我发现很难在 .NET API 中找到有关 ADFS 的有用示例。它们通常是 Azure AD 或 .NET Framework。
通过收集各种资源,我能够生成以下代码:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "Bearer";
options.DefaultChallengeScheme = "Bearer";
})
.AddOpenIdConnect("Bearer", options =>
{
options.ClientId = configuration["ClientId"];
options.Authority = configuration["Authority"];
options.MetadataAddress = configuration["MetadataAddress"];
options.TokenValidationParameters = new TokenValidationParameters
{
ValidAudiences = new[] { options.ClientId }
};
options.RequireHttpsMetadata = false; // Set this to true in production environments
});
https://adfs.<company>.local/adfs
https://adfs.<company>.local/federationmetadata/2007-06/federationmetadata.xml
。我 do 知道 OpenID 使用 .well-known/openid-configuration
格式,但使用此代码的示例使用 XML 文件。我觉得重要的一点是 ADFS 服务器使用的是自签名证书,因为这是本地测试服务器。
我不知道问题出在哪里。由于我的理解有限,可能是ADFS配置错误,也可能是代码问题,我不知道。
如果有人知道哪里出了问题,请告诉我!这个主题似乎非常局限于企业界,因为我只能找到非常数量有限的类似情况的在线示例。