Reinventing the Wheel - not just another working title

not just another working title

Reinventing the Wheel

We’ve needed to batten down the hatches on the application we’ve been working on to make sure that it will be secure come go live (which is today incidentally, I’ve been sitting on this post for a while) and the task fell to me to delve into the murky waters of Web Service Security (WSS in future for the TLA buffs). Our application is, in a nutshell, a smart client forms app connecting to an ASP.NET Web Service – both in C#, and we needed to secure the users calling the web services, as well as prevent the ‘replayability’ of the soap requests. Now, our initial login method call is secure as we can get it, of that we’re pretty confident, so all we needed to do was secure the rest of it. Ok... Enough back story, but two things first:
  1. An important point to make at this juncture, is that a lot of what lies below is my hackery of concepts that form the building blocks of the Web Service Extensions framework (WSE 1, 2, and 3). The correct way to implement WSS would be to use it, but unfortunately at this late stage of our project it introduced an unacceptable risk for us to run with it. (This is the excuse known as “my boss wouldn’t let me”... It’s my excuse and I’m sticking with it so nyah.
  2. This is really the kind of stuff that should be included from the ground up in your design. We were just very lucky that we got away with doing it now, piggy backing of our request provider code.

Todo:

·         Ensure that multiple (replayed) calls to the service fail

·         That the user is authenticated against both the message sender as well as a unique identifier kept in session on the server.

·         That the unique identifier kept in session expires properly, and also gets renewed properly

·         The failing of authentication fails gracefully on the user interface, but is also handled locally so as to not happen mid query (pre-emptive).

 

Implementation:

·         Client contacts the server using a secure login procedure, and as a part of this procedure the server generates a Token comprised of a unique identifier that it saves in a dictionary collection (which will contain some kind of custom struct to hold all of the information) along with the creation time (to facilitate session expiry) and then returns this Token to the client for subsequent requests.

·         On subsequent requests the client will generate it's own unique identifier in the form of a Key with which to sign the request as unique (possibly just use the MessageID). The Token will then be salt-ed with this Key and then encrypted using sha1. The token will not be sent to the server, only the final message Signature will be sent along with the originating user and  the Key.

·         On the server side, this message will be received and the originating user validated against (using its own unique identifier) the database.  Then the Token will be retrieved from the dictionary, and the same process of salt-ing and sha1-ing the Token and Key will be performed and then matched against the message Signature as well as  against it's expiry date to see whether or not to allow the request. If this does not match, then the request will be discarded with a thrown exception, otherwise the service will then proceed to check the Key against a stored collection of recently used Keys to make sure that it isn't a replayed request. If the Key is found, then the message is rejected with an exception, otherwise the Key is stored for future comparison, the Token expiry is refreshed and processing continues.

 

 

Security Diagram

 

That's what we've done at a very high level, and it works. We've had some trouble with synchronising between the client and server, but we'll iron that out over time. For the moment what we do is throw a custom security exception and handle it elegantly on the client by prompting the user to log in again. This opens up a new kettle of fish though, because the ASP.NET web services do not propgate the custom exceptinos very well, but that is a discussion that'll have to wait for another day.

 Here are the resources I found useful, and again please note that most of them are regarding WSE, and I would highly recommend using it - I will be in future:

http://www.codeproject.com/KB/webservices/WS-Security.aspx

http://en.wikipedia.org/wiki/WS-Security

http://msdn.microsoft.com/en-us/library/ms977317.aspx


 

Posted: Jun 02 2008, 06:46 AM by mikegeyser | with no comments
Filed under: ,
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: