Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have a WCF rest service that will be consumed by multiple clients. The information returned by the client requires me to know who they are, so that I can return information specific to them.

Is the best way to approach this type of design to authenticate them and return a token for their session, then pass this token along with every request?

Thanks.

share|improve this question
2  
Should be migrated: stackoverflow.com/questions/7551/… –  user2567 Apr 20 '12 at 10:42
2  
@Pierre303 I disagree. This is more of a best practices question. –  Tom Squires Apr 20 '12 at 10:48
    
Yes, as @TomSquires says, I'm looking for best practices. Thanks. –  Brian Mains Apr 20 '12 at 10:49
1  
@TomSquires: Guys, did you follow the link I suggested? It is a post titled "Best Practices for securing a REST API / web service" with perfectly valid answers. –  user2567 Apr 20 '12 at 10:51
2  
@Pierre303 That question was asked in 2008 before Programmers was a glimmer in Atwood's eye. It should be historical locked on their side, but if that same question were asked on SO today it would rightfully be migrated here. It is a relevant link however. –  maple_shaft Apr 20 '12 at 11:17

4 Answers 4

One possible way to do this would be with a cookie-based (or URL parameter-based) session token, as you suggest. However, passing a session token like that violates the HATEOAS principle. For a "truly" REST-ful service, you should avoid maintaining server state.

If you're using HTTPS, it may be wise to consider using the built-in authorisation/authentication (Sec. 14.8) mechanisms in HTTP. Namely, using the WWW-Authenticate and Authorization headers to pass Basic Auth information back to the server on each request. This allows you to maintain statelessness, but because you're using HTTPS, it is also secure. If you're not using HTTPS, then maybe you should be :).

Using OAuth with the HTTP mechanism is another alternative to Basic Auth, but its complexity is not necessary if you're already encrypting the channel with HTTPS. Because OAuth requests cannot be replayed, and do not reveal the key, they're acceptable over plain-old HTTP, whereas Basic Auth is not.

So, in summary:

  • You can get away with simple Basic Auth, which is built into most HTTP client libraries, if you're communicating exclusively over HTTPS. Basic Auth is in general much simpler to implement.
  • You should not use Basic Auth if you are not using HTTPs. Instead, use 2-legged OAuth.
  • In either case, use the WWW-Authenticate and Authorization headers to share credential information
share|improve this answer

If you are looking for ideas about security for REST web services then look at the OpenAuth spec Appendices describing the "handshake".

http://oauth.net/core/1.0/#anchor27

Creating web services that adhere to OpenAuth standards is probably one of the more secure ways that this can be done. It can give you ideas on authentication, authorization strategies.

The following is an example taken from the Authorization header in a GET or POST:

Authorization: OAuth
    oauth_consumer_key="xxxxxxxxxxxx",
    oauth_token="xxxxxxxxxxxx",
    oauth_nonce="xxxxxxxxxxxx",
    oauth_timestamp="1184242096",
    oauth_signature_method="HMAC-SHA1",
    oauth_version="1.0",
    oauth_signature="xxxxxxxxxxxxxxxxxx" 

I am not going to go into all the details of OpenAuth but essentially it allows a client to provide a consumer key that identifies the client, a token that identifies the user, and a signature that represents the Base64 encoded bytes of the encrypted signature to verify that the request has not been tampered or altered on transport.

Building the signature string typically involves the percent encoded combination of the entire request, parameters, as well as consumer key, token, nonce, and a consumer secret which the client should keep safe. Once this signature string has been built and percent encoded it can then by encrypted, and those encrypted bytes can be constructed into a Base64 encoded string that is included in the Authorization header.

If you perform this over SSL, then this is undoubtedly one of the most secure ways to handle authentication/authorization of a REST based web service.

share|improve this answer

Short of going with certificates or OpenID, I've found that a token-based approach is the simplest solution. In one enterprise service app I worked on, we had an Authentication Service that exposed a REST endpoint for authentication and responded with a token that was then passed in a header with all subsequent requests to other endpoints. Each operation would inspect the header for the token and take the appropriate action based on whether it was there or not and, if present, if the token represented a user with the required authorization.

My suggestion is that you look into a claim-based security model. First, it makes this MUCH easier to implement as you can keep the server stateless by encapsulating all of the user's claim information inside the token. And, second, it is the model that Microsoft and many others are moving into. If you are doing .NET development, look into the Windows Identity Foundation. This is currently an add-on to the .NET framework but will be built into Windows 8 (and is, in fact, the default security model in .NET 4.5).

share|improve this answer

I lean towards HTTPS and Basic Auth because web client support is ubiquitous. I also prefer not implementing a session if I don't have to. It's unnecessary complexity and it's not really RESTful. REST requests should be standalone, so you send your credentials and whatever other information is required to create your request. However, there may be reasons/requirements that necessitate compromising on OAuth rather than HTTPS and Basic Auth.

Resources should have the appropriate acls set to control who can and cannot access them. A request is received from an authenticated user it is only successfully fulfilled if the user has access to the resource.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.