Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing password in forms authentication cookie - ASP.NET and WCF calls

For my web app security I'm using FormsAuthentication / MembershipProvider with a non persistant cookie.

My application interacts with some web services, these also use the Membership providers.

User passwords are hashed in the database.

The problem is the person logged into application the web service needs to authenticate with the web service using his username and password every time a page is loaded. BUT once the user has logged in his password is not retreivable as it is hashed.

I was wondering if the password could be stored securley in the Authentication cookie so that the user can authenticate with the web service.

Or a better idea!

EDIT I LIKE JOHNS IDEA BELOW BUT HAVE 4 COMMENTS ON THE MECHANICS THAT I WANT TO RESOLVE BEFORE GOING DOWN THAT ROUTE...

like image 777
AJM Avatar asked Dec 03 '22 07:12

AJM


1 Answers

I agree with @John's answer that using throwaway token is better than storing the credentials.

For the token you could generate some random GUIDs and store it in the database.

As an alternative that does not require coordination between your ASP.NET application and the WCF service, you could send a signed document as token.

  1. create an XML or JSON document with signed time, user name, and signer's name (ASP.NET app).
  2. generate a hash of the above document.
  3. sign the hash using asymmetric encryption (use private key).

All WCF has to do is validate the hash and the signature. So this does not involve hitting the same database. Using the signed time, you can expire the token in fixed time.

Edit: The idea is based on public-key cryptography (also known as asymmetric key algorithm, public/private key). If you encrypt something with a private key you can decrypt it back only using the corresponding public key; and if you encrypt something with a public key you can decrypt it only using the corresponding private key. See Implementing RSA in C# for how code would look like in C#. Why is this useful? Because we can use this to implement digital signatures. A digital signature is a way to prove that I and only I wrote something, and no one else.

Following the above mentioned step generates a signature. You first need to define a canonical form of "let this guy in" document. Usually an asymmetric key algorithm can't handle too big input, so you generate a hash out of it, and you encrypt the hash using your ASP.NET application's private key. The resulting signature can only be decrypted using you application's public key. Finally you can package all three components (original document, hash, and signature) into some format like XML or JSON and send it as token.

As an example, let's say you use JSON format for everything. First, the original "let this guy in document":

{"UserName":"Foo","SignedTime":"2009-07-09T00:00:00","Signer":"ASP.NET APP1"}

Next, you generate a SHA-1 hash of the above string, which is byte[] and encode it with modified Base64 encoding or something, which would look something like:

b2YgYW55IGNhcm5hbCBwbGVhc3VyZS4 

The above is bogus string, the actual stuff may look longer. You then take the hash byte[] and encrypt it using RSA, which generates another byte[] so encode that too with modified Base64:

mxlIGdlbmVyYXRpb24gb2Yga25vd2xfo34

Finally, you make another JSON document to store all the above.

{"UserName":"Foo","SignedTime":"2009-07-09T00:00:00","Signer":"ASP.NET APP1","Hash":"b2YgYW55IGNhcm5hbCBwbGVhc3VyZS4","Signature":"mxlIGdlbmVyYXRpb24gb2Yga25vd2xfo34"}

The final JSON document becomes your passwordless token. Pass it to WCF service. The WCF service takes the token, construct the original document by removing the hash and signature:

{"UserName":"Foo","SignedTime":"2009-07-09T00:00:00","Signer":"ASP.NET APP1"}

Follow the same algorithm to generate the hash and verify it's the same. Decrypt the Signature using the public key of the ASP.NET app and see if it becomes the hash. At this point, the document is verified to be signed by the signer. Check the current time and the signed time and see if the token is still valid. All you need is a way to distribute public keys between two code base, which could be loaded from XML.

like image 74
Eugene Yokota Avatar answered Jan 03 '23 13:01

Eugene Yokota