Client Certificate Mapping Authentication in self
Is it possible (and if so, how?) to configure a self hosted owin endpoint to use client certificate mapping authentication with A/D? IIS has this feature link, but so far I have not found an equivalent for self-hosted endpoints.
The way in which I have gotten this to work though (bearing in mind this approach is probably not 100% foolproof), is a 2-step process by using a combination of authenticationSchemeSelectorDelegate and OWIN.
This will choose the appropriate AuthenticationScheme (allowing requests containing a cert through, otherwise deferring to NTLM authentication)
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;
}
This will read the contents of the cert and populate the "server.User" environment variable accordingly
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;
}
}
Is there not a better/standardized way?
I have not seen any standard components built for this yet. That said, it should be possible to clean up your code a little:
上一篇: 从OBD适配器读取VIN
下一篇: 客户端证书映射身份验证