Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Use Active Directory Authentication with ASP.NET Web API?

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?

like image 584
The Light Avatar asked May 01 '13 08:05

The Light


People also ask

How do I add authentication to web API?

In IIS Manager, go to Features View, select Authentication, and enable Basic authentication. In your Web API project, add the [Authorize] attribute for any controller actions that need authentication. A client authenticates itself by setting the Authorization header in the request.


1 Answers

I've been doing a fair bit with AD lately and I cannot think of another way of handling this to be honest.

It might make more sense to use an OAuth type approach. Provide a token type route that will take the username and password initially and return a self authored and encrypted token back to the callee. Once that first initial call is made send the token back to the callee and then they can use that token in the Authorisation header for each subsequent call to the API.

The tokens would be valid for one call or a very short space of time. Each time you deem the token to be used, issue another one.

You could also look at using a custom OAuth implementation for this and rather than use a database for the authentication process use your AD identity store and make use of OAuth Bearer tokens. Since you're using SSL this is actually a good fit for your scenario.

like image 159
Jammer Avatar answered Oct 23 '22 12:10

Jammer