I am creating a secure (SSL) public service where the users credentials reside in Active Directory. I want to leverage ServiceStack\'s Authentication and have read over the wiki
Here is what Demis Bellot said on twitter. Probably possible but needs more research.
Not something I've investigated, don't work in the Win/Active Directory anymore. Requires some R&D to find/resolve the issue
I did eventually get a prototype service working with AD. I implemented the CredentialsAuthProvider. Now this is not tied to ASP.NET IWA at all, but does easily check to see if the user is in AD. Hopefully this might help someone.
public class LDAPAuthProvider : CredentialsAuthProvider
{
public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
//Check to see if the username/password combo is valid, an exception will be thrown if the username or password is wrong
try
{
DirectoryEntry entry = new DirectoryEntry(ConfigurationManager.AppSettings["TargetOU"], userName, password);
object nativeObject = entry.NativeObject;
}
catch (Exception)
{
//This means the username/password combo failed
return false;
}
return true;
}
}
I've also hooked up ServiceStack with Integrated Windows Authentication (for a corporate application), and the key was to skip trying to integrate it with ServiceStack's AuthProviders entirely, since the general approach of IWA doesn't deal with credentials in your application code -- it's handled by the web server. What I did was:
Configure the site/application in IIS so that Windows Authentication was the only enabled option. (No Anonymous access allowed.) This means IIS itself will take care of the challenge-response (HTTP 401/200) sequence with unauthenticated users, and handles the authentication part of the process for you.
Implement ServiceStack's IHasRequestFilter
(an HTTP pre-request filter) as an Attribute (e.g., [AdminOnly]). This filter's RequestFilter method fetches the current username from HttpContext (HttpContext.User.Identity.Name
), looks it up from a repository (which could be a SQL database, flat file, etc.), caches results using ServiceStack's ICacheClient
(memory cache, Redis, etc.), and throws a 403 HttpError if unauthorized.
With this done, all that was necessary was to add the attribute to classes or methods where desired (which gets this authentication/authorization into the service pipeline where desired), and register my desired cache provider in my AppHost implementation, e.g.:
container.Register<ICacheClient>(new MemoryCacheClient() { FlushOnDispose = false });
It works beautifully.