We have a Web API application which provides a number of web methods that clients can call and consume. It's going to be hosted in IIS and have SSL setup.
The user credentials are stored in Active Directory but the clients are not just within our domain, they can be anywhere in the world so we my understanding is we can't use Windows Integrated Authentication.
What's the best way to authenticate the users in our scenario as explained above?
Should I be asking the users to pass username/password in the header with every request they make? Then I validate the user credentials against our Active Directory programmatically (we already have a component which does that) e.g. by creating a custom ActionFilter which runs before each action gets executed?
Another approach would perhaps be to create a HttpModule which runs before every request and does the authentication and if invalid aborts the request.
My Custom Attribute would look like this:
public class ActiveDirectoryAuthAttribute : ActionFilterAttribute
{
// todo: load from config which can change depending on deployment environment
private static readonly bool ShouldRequireHttps = false;
public override void OnActionExecuting(HttpActionContext actionContext)
{
IPrincipal principal = this.Authentiate(actionContext);
if (principal == null)
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
else
{
this.SetPrincipal(principal);
}
}
private IPrincipal Authentiate(HttpActionContext actionContext)
{
if (IsUriSchemaValid(actionContext.Request.RequestUri))
{
// is the client certificate known and still valid?
// is IP valid?
// find user credentials and validate against AD
// create the Principle object and return it
}
return null;
}
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
private static bool IsUriSchemaValid(Uri uri)
{
bool result = true;
if (ShouldRequireHttps)
{
if (!string.Equals(uri.Scheme, "https", StringComparison.InvariantCultureIgnoreCase))
{
result = false;
}
}
return result;
}
}
Then inside my controller action I can get access to the Principle object:
IPrincipal principle = this.User;
What's the best way to authenticate/authorize the users in our scenario as explained above?
In Above, how to create an object from IPrinciple? Is there any existing .NET class or I'd have to create my custom class?