在我的 .NET 7 项目中,我的身份验证和授权配置如下:
builder.Services.AddAuthentication()
.AddNegotiate(NegotiateDefaults.AuthenticationScheme, _ => { })
.AddCertificate(CertificateAuthenticationDefaults.AuthenticationScheme,
options => {
options.RevocationMode = X509RevocationMode.NoCheck;
options.ValidateCertificateUse = true;
options.ValidateValidityPeriod = true;
options.Events = new CertificateAuthenticationEvents() {
OnAuthenticationFailed = InvalidCertificates.InvalidCertificateHandler,
OnCertificateValidated = ValidCertificates.ValidCertificateHandler
};
});
builder.Services.AddAuthorization(options => {
options
.AddPolicy(AuthorizationsConstants.AuthenticatedUser,
policy => {
policy.RequireAuthenticatedUser();
policy.AuthenticationSchemes = new[] { NegotiateDefaults.AuthenticationScheme, CertificateAuthenticationDefaults.AuthenticationScheme };
policy.Requirements.Add(new ValidCertificateRequirement());
});
options
.AddPolicy(AuthorizationsConstants.ReportAuthorization,
policy => {
policy.Requirements.Add(new ReportAuthorizationRequirement());
});
});
在我的本地计算机上,授权处理程序中的 context.User 有两个身份 - ClaimsIdentity 和 WindowsIdentity。
我的网站配置为使用 ClientCertificateMappingAuthentication。 这是因为 IIS 服务器是域的一部分,并且所有用户在其证书映射到的 Active Directory 中都有帐户。
当我最初将代码部署到站点时,收到错误:“协商身份验证处理程序不能在直接支持 Windows 身份验证的服务器上使用。为服务器启用 Windows 身份验证,协商身份验证处理程序将遵循它。”
因此,我更新了站点,为应用程序启用 Windows 身份验证。 一旦我这样做了,错误就消失了。
当我使用 .NET Framework 时,IIS 使用从 Active Directory 检索到的信息填充用户主体。但是,这不会发生在我的网站上。 授权处理程序中的 context.User 只有一个 ClaimsIdentity。
对我来说,在 Negotiate 中似乎没有调用 AuthenticateAsync 方法,因为我有一个继承 IClaimsTransformation 的类。 在我的本地计算机上,此类被调用两次:一次用于协商方案,一次用于证书方案。
我想访问由 Active Directory 填充的用户的声明 - 部分是为了确保用户实际上已经通过 AD 进行了身份验证。
此时,我完全不知道发生了什么或如何解决它。
更新:
我更新了失败请求跟踪以记录所有 HTTP 状态代码。 我认为请求的相关部分如下:
我猜这里的主要问题是,由于证书映射 NTLM 设置为 false,因此不会触发该方案,因为名称中包含协商。
所以,我相信下一步可能是想出一个自定义的身份验证方案,或者还有其他我可以使用但我不知道的东西吗?