WebApi authorization filter with token in json payload

I studied Authorization with AspNetWebApi and the information is a bit rare on this subject.

I have the following options:

  • Skip API token in query string
  • API transfer character as header
  • Pass API Badge Using Basic Auth
  • Passing API token on request payload in json.

Generally recommended method?

I am also interested in point 4), how could I inspect the json payload in the OnAuthorization method on the AuthorizationFilterAttribute to check if the API token is correct?

+4
asp.net-web-api
May 03 '12 at
source share
1 answer

If you want a truly secure authentication option, then, for example, OAuth is the way to go. This blog post provides a fairly thorough example using the now deprecated WCF web API, but many of the code is safe. Or at least use basic HTTP authentication, as shown in this post. As Aliostad notes, make sure you use HTTPS if you go along the basic authentication route so that the token remains secure.

If you decide that you want to collapse your own (which will almost always be much less secure than any of the above options), below is an example of the code you will need for an AuthorizationHanlder if you are sending an HTTP header route. Keep in mind that a good chance of how UserPrinicipal is handled in web API classes can change, so this code is only good for the first preview. You will need to connect to the AuthorizationHandler as follows:

GlobalConfiguration.Configuration.MessageHandlers.Add(new AuthenticationHandler()); 

Code for header token:

 public class AuthenticationHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { var requestAuthTokenList = GetRequestAuthTokens(request); if (ValidAuthorization(requestAuthTokenList)) { //TODO: implement a Prinicipal generator that works for you var principalHelper = GlobalConfiguration.Configuration .ServiceResolver .GetService(typeof(IPrincipalHelper)) as IPrincipalHelper; request.Properties[HttpPropertyKeys.UserPrincipalKey] = principalHelper.GetPrinicipal(request); return base.SendAsync(request, cancellationToken); } /* ** This will make the whole API protected by the API token. ** To only protect parts of the API then mark controllers/methods ** with the Authorize attribute and always return this: ** ** return base.SendAsync(request, cancellationToken); */ return Task<HttpResponseMessage>.Factory.StartNew( () => new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent("Authorization failed") }); } private static bool ValidAuthorization(IEnumerable<string> requestAuthTokens) { //TODO: get your API from config or however makes sense for you var apiAuthorizationToken = "good token"; var authorized = requestAuthTokens.Contains(apiAuthorizationToken); return authorized; } private static IEnumerable<string> GetRequestAuthTokens(HttpRequestMessage request) { IEnumerable<string> requestAuthTokens; if (!request.Headers.TryGetValues("SomeHeaderApiKey", out requestAuthTokens)) { //Initialize list to contain a single not found token: requestAuthTokens = new[] {"No API token found"}; } return requestAuthTokens; } } 
+5
May 03 '12 at 15:55
source share



All Articles