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

后端 未结 3 464
野趣味
野趣味 2021-02-04 20:52

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

3条回答
  •  生来不讨喜
    2021-02-04 21:32

    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.

提交回复
热议问题