none
REST service and username password validation

    Question

  • Hi all, I'd like to verify my understanding is correct (in a way hoping it is not) and get some advice.

    Scenario - I have a REST service exposed to be consumed solely by a windows forms application (the reason for choosing rest is primarily to benefit from caching, I'll get back to this).

     

    So far everything works like a charm, but we now need to add authorisation to the service whereby only specific users can have access to the data (in an all-or-nothing fashion) I have custom logic for authentication of the users, so ideally I would have liked the client software to provide the cerdentials, and to be able to write custom UsernameValidator on the service side to validate them.

    However - I've read a fair amount now and it appears that this is not possible?

    Currently I'm using webHttpBinding which seem to not support custom username validation for TransportCredentialOnly security? If that's right, what is the best alternative?

    I've been thinking of various options, my favorite right now is two tier - Use certificate (distributed with the application) to ensure only calls from the application are accepted and add custom HTTP headers for the cerdentials, that would be processed by a custom authorisation manager. would that work? is there a better alternative?

    One of the things I have to consider is the impact of any solution on caching - if caching becomes irrelevant due to the security implementation, I might as well move away from REST and have the full blown WCF capabilities, but we benefit greatly form the caching today (the nature of the service is that a lot of data is being returned and many calls are repetitive).

    With the approach I've described above, where the only valid consumer is the application, I could implement a second check in the application, so that if data is returned from, say, a proxy cache, the application would reject it.

    One last note - both the application and the service exist solely on our intranet, this means that encryption is not needed and that we're slightly less concerned with people going out of their way to get data they shouldn't be getting (such has hacking the application), but we can't assume any AD as multiple ADs are in play, not all with trust relationship


    Yossi Dahan http://www.sabratech.co.uk/blogs/yossidahan [To help others please mark replies as answers if you found them helpful]
    • Edited by Yossi Dahan Friday, June 25, 2010 9:28 AM trying to apply some formatting!
    Friday, June 25, 2010 9:21 AM

Answers

  • Hi Yossi,

    Regarding on your application scenario, I think your assumption is correct.

    When you choose WebHttpBinding, it can provides outputcache(added in .NET 4.0), however, you cannot utilize the message layer security such as username authenticaiton with custom authentication manager.

    If you want to add custom username/password like authentication/validation at service-side, I think your idea about using custom http header is reasonable since that is the proper place for http request to carry additional information for each request without affecting the operation contract itself.  Also, at service-side, you can use a custom authorizationManager to check the values in the request context:

    #How to: Create a Custom Authorization Manager for a Service
    http://msdn.microsoft.com/en-us/library/ms731774.aspx

    Or if you want to implement your own identity/principal model at service-side, you can use custom IAuthorizationPolicy to genrate custom principal/identity instance based on custom properties in request context and assign it to the OperationContext.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Yossi Dahan Monday, June 28, 2010 8:11 AM
    Monday, June 28, 2010 7:43 AM
    Moderator

All replies

  • Hi Yossi,

    Regarding on your application scenario, I think your assumption is correct.

    When you choose WebHttpBinding, it can provides outputcache(added in .NET 4.0), however, you cannot utilize the message layer security such as username authenticaiton with custom authentication manager.

    If you want to add custom username/password like authentication/validation at service-side, I think your idea about using custom http header is reasonable since that is the proper place for http request to carry additional information for each request without affecting the operation contract itself.  Also, at service-side, you can use a custom authorizationManager to check the values in the request context:

    #How to: Create a Custom Authorization Manager for a Service
    http://msdn.microsoft.com/en-us/library/ms731774.aspx

    Or if you want to implement your own identity/principal model at service-side, you can use custom IAuthorizationPolicy to genrate custom principal/identity instance based on custom properties in request context and assign it to the OperationContext.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Yossi Dahan Monday, June 28, 2010 8:11 AM
    Monday, June 28, 2010 7:43 AM
    Moderator
  • Thanks Steven

     

    This is very helpful. 

    Could you (or anyone) also provide any insights into the implication on caching? if we were to able to use Windows authentication or anything else that's supported, and caching was used - would caching occur 'per user'? not happen at all or do we run the risk how users seeing other user's data? 

    Given this, if I move to the authorisation manager approach -  I assume my risk increases, can that be mitigated? 

    I've read elsewhere a suggestion that at a point like this one should consider 'backing-off' from REST, but I didn't think this was such a complicated requirement...

     

    Thanks 

     

    Yossi


    Yossi Dahan http://www.sabratech.co.uk/blogs/yossidahan [To help others please mark replies as answers if you found them helpful]
    Monday, June 28, 2010 8:17 AM
  • Thanks for your quick reply Yossi,

    As for the caching, WCF 4.0 REST utilize the ASP.NET output cache, and the cache on service is applied through a cache profile. Therefore, I think you should look into the cache profile settings and apply certain cache dependency so as to make the service cache different data based on the certain criteria. For example, the cache profile support cache  by http header. e.g.

    <outputCacheProfiles> 
       <add name="profile1" location="Server" duration="60" 
           varyByHeader="Accept"/> 
      </outputCacheProfiles>
    For more information, you can refer to the ASP.NET output caching and cache profile:


    #Output Caching and Cache Profiles
    http://msdn.microsoft.com/en-us/library/aa661294.aspx



    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Monday, June 28, 2010 9:19 AM
    Moderator