10

I have a Web API project which provides the access to only Authorized users based on roles. We plan to scale to multiple such API projects in the near future which will use the same Authorization token. What I am doing is using a separate project which authenticates the user (using Facebook, Google or ActiveDirectory or any other authentication provider), and then generate an Authorization token which is consumed by all the API servers. To enable decryption of the token, I am sharing the machine key via web.config among all the application. This works fine. Now I would like to change the MachineKey every once in a while and share it among all the applications that utilize the Authorization token.

  1. How do I update the machineKey at run time among all the applications?
  2. Is there a programmatic way to achieve the same?
  3. I have read in a blog that updating machineKey's is not a good practice. If so, how do I avoid using the machine key altogether and create a system where the key's are not static?

My idea is to separate out the Authorization project from my WebAPI projects so that I don't implement and authentication system within all the WebAPI projects. Any pointers would be very helpful.

Shouvik
  • 11,350
  • 16
  • 58
  • 89

3 Answers3

4

Extended the implementation shown on the following stackoverflow answer to meet your requirements. I will update the code in a couple of days on how you can achieve this.

Community
  • 1
  • 1
RAJESH JAIN
  • 106
  • 2
0

You could let the APIs request the Authorization-Service to confirm the token from the Client and in that same request get the ID-data from the Service to the API. To reduce the traffic to the Auth-Service, it could hand out short-lived access-Tokens to the APIs with an expiration date, which need to be refreshed after a few minutes, or if they are critical, could be revoked directly from the Auth-Service calling out to the APIs.

Your system sounds a lot like an OAuth-scheme to me. I would not suggest trying to go fully compliant unless you plan for other use cases like mobile devices etc. accessing your services, but you can read up on how they do it and implement what seems relevant for your needs.

Manuel Schweigert
  • 4,884
  • 4
  • 20
  • 32
  • I have considered your implementation and I have already architected the solution on similar lines. The thing is, I am interested in using the Windows based authentication system to manage my authorization. This way I can use the `[Authorize]` attribute over the web API's without much change to my API projects. I am currently I am sharing the `machineKey` of my token generation system with the API projects. This way, there is no need to verify the token from the Authorizing server. I just want to change the machineKey dynamically so that it's not static. – Shouvik Sep 15 '14 at 17:12
0

As suggested by Rajesh, I believe what I am looking for is a trivial enhancement of his link. Essentially I need to create a function that sets my key in the Protect method.

private IDataProtector protector;

public string Protect(AuthenticationTicket ticket)
{
    protector = new AesDataProtectorProvider(functionGenerateKey()); 
    //functionGenerateKey is a function that generates a new key and informs 
    //the subscribers to avail new key
    var ticketData = this.serializer.Serialize(ticket);
    var protectedData = this.protector.Protect(ticketData);
    var protectedString = this.encoder.Encode(protectedData);
    return protectedString;
}

public SecureTokenFormatter(string key)
{
    this.serializer = new TicketSerializer();
    //this.protector = new AesDataProtectorProvider(key); -> Remove the initialization of this protector as I am doing it in the above function. 
    this.encoder = TextEncodings.Base64Url;
}

The rest of the implementation is pretty standard in the code written by Barguast

Community
  • 1
  • 1
Shouvik
  • 11,350
  • 16
  • 58
  • 89