是否可以(如果可以,如何?)配置一个自托管的 owin 端点以使用带有 A/D 的客户端证书映射身份验证?IIS 有这个功能链接,但到目前为止我还没有找到自托管端点的等价物。
虽然我得到这个工作的方式(记住这种方法可能不是 100% 万无一失的),是通过结合使用 authenticationSchemeSelectorDelegate 和 OWIN 的两步过程。
这将选择适当的 AuthenticationScheme(允许包含证书的请求通过,否则推迟到 NTLM 身份验证)
public void Configuration(IAppBuilder appBuilder)
{
var listener = (HttpListener)appBuilder.Properties[typeof(HttpListener).FullName];
listener.AuthenticationSchemeSelectorDelegate += AuthenticationSchemeSelectorDelegate;
}
private AuthenticationSchemes AuthenticationSchemeSelectorDelegate(HttpListenerRequest httpRequest)
{
if (!httpRequest.IsSecureConnection) return AuthenticationSchemes.Ntlm;
var clientCert = httpRequest.GetClientCertificate();
if (clientCert == null) return AuthenticationSchemes.Ntlm;
else return AuthenticationSchemes.Anonymous;
}
这将读取证书的内容并相应地填充“server.User”环境变量
public class CertificateAuthenticator
{
readonly Func<IDictionary<string, object>, Task> _appFunc;
public CertificateAuthenticator(Func<IDictionary<string, object>, Task> appFunc)
{
_appFunc = appFunc;
}
public Task Invoke(IDictionary<string, object> environment)
{
// Are we authenticated already (NTLM)
var user = environment["server.User"] as IPrincipal;
if (user != null && user.Identity.IsAuthenticated) return _appFunc.Invoke(environment);
var context = environment["System.Net.HttpListenerContext"] as HttpListenerContext;
if (context == null) return _appFunc.Invoke(environment);
var clientCertificate = context.Request.GetClientCertificate();
// Parse out username from certificate
var identity = new GenericPrincipal
(
new GenericIdentity(username), new string[0]
);
environment["server.User"] = identity;
}
}
没有更好/标准化的方式吗?