2014-01-23 86 views
1

我想要完成的是在我的MVC應用程序中使用相同的接口和其他一些方法創建cookie對象/方法的替代品。如何擴展MVC5中的HttpCookie對象?

我想補充的方法是創建加密的Cookie中的自定義方法。這些方法基本上只是在設置之前加密cookie中設置的數據。讀取cookie後,反向方法會解密數據。

我想更換內置的Cookie對象是這樣我就可以重新設計的默認方法的行爲以允許自動加密/解密的方式的原因。

+0

你可以嘗試在現有的Cookie類上使用擴展方法。 –

+0

我知道這存在的Web API。也許你可以適應MVC? http://www.asp.net/web-api/overview/working-with-http/http-cookies –

回答

1

當的HttpCookie類是密封的,不能被繼承,你可以讓你的生活做一個加密的cookie類,易於使用的操作符重載容易。

public class EncryptedCookie 
{ 
    public string Name { get; set; } 

    public string Value { get; set; } 

    private byte[] encryptionKey; 

    private byte[] hmacKey; 

    public EncryptedCookie() 
    { 
     // setup keys 
     encryptionKey = Convert.FromBase64String(ConfigurationManager.AppSettings["encryption-key"]); 
     this.hmacKey = Convert.FromBase64String(ConfigurationManager.AppSettings["hmac-key"]); 
    } 

    public static explicit operator HttpCookie(EncryptedCookie cookie) 
    { 
     if (string.IsNullOrEmpty(cookie.Name)) 
     { 
      throw new ArgumentException("Encrypted cookie must have a name"); 
     } 

     if (string.IsNullOrEmpty(cookie.Value)) 
     { 
      throw new ArgumentException("Encrypted cookie must have a value"); 
     } 

     return new HttpCookie(cookie.Name, cookie.Encrypt()); 
    } 

    public static explicit operator EncryptedCookie(HttpCookie cookie) 
    { 
     if (cookie == null) 
     { 
      return null; 
     } 

     var result = new EncryptedCookie { Name = cookie.Name }; 
     result.Decrypt(cookie.Value); 
     return result; 
    } 

    private string Encrypt() 
    { 
     var encryptor = new Encryptor<AesEngine, Sha256Digest>(Encoding.UTF8, this.encryptionKey, this.hmacKey); 
     return encryptor.Encrypt(this.Value); 
    } 

    private void Decrypt(string cookieValue) 
    { 
     var encryptor = new Encryptor<AesEngine, Sha256Digest>(Encoding.UTF8, this.encryptionKey, this.hmacKey); 
     string plainText = encryptor.Decrypt(cookieValue); 
     if (string.IsNullOrEmpty(plainText)) 
     { 
      throw new ArgumentException(); 
     } 

     this.Value = plainText; 
    } 
} 

要使用這個類,你需要我的加密類以及bouncycastle。此類對您輸入的任何值執行加密,並在已從響應中設置的http cookie中進行解密。有一件事很好,它會自動生成IV和HMAC,以驗證沒有篡改cookie值。您將需要兩個單獨的密鑰,一個用於HMAC,一個用於加密。因爲它們是加密系統中最重要的部分,所以能夠明智地生成它們。

您可以Encrypt and decrypt a string下找到加密類或者你可以用你想,如果有什麼東西你公司專門用來使用任何覆蓋。

最後用簡單的創建一個加密的Cookie,並把它添加到響應:

EncryptedCookie cookie = new EncryptedCookie { Name = "MyCookie", Value = "Hide this!" }; 
Response.Cookies.Add((HttpCookie)cookie); 

當你想解密簡單地把餅乾回加密的Cookie:

var cookie = (EncryptedCookie)Request.Cookies["MyCookie"]; 
Response.Write(cookie.Value); 
+0

這是非常接近我的目標。唯一缺少的是如何使它自動確定它是否是加密的cookie並自動執行解密。 – Hades

+0

你將無法做到這一點,因爲它將被混合到具有未加密cookie的cookie集合中。你可以在技術上杜絕isencrypted屬性,然後投所有的cookie加密Cookie,但會帶來不必要的開銷和額外的代碼,我想你想避免.. – nerdybeardo

+0

難道在HTTP處理程序層面上做了什麼?例如,在我想要加密的任何cookie中,我只需在cookie名稱上設置一個字符串前綴即可。然後,任何具有該處理程序前綴的cookie都可以通過請求/響應管道自動加密/解密。那有意義嗎? 我正在尋找一種方法讓我的項目開發人員不必真的想太多。 – Hades

0

我不相信有一種方法。揭示Cookie實例的HttpRequest/HttpResponse對象都是密封的,因爲它本身就是HttpCookie類。

您可能可以通過使用HttpResponseWrapper/HttpRequestWrapper基類重新實現請求/響應來解決問題,但它似乎有很多工作。

祝你好運!

+0

感謝您的回覆。上面的nerdybeardo的答案更接近我正在尋找...看到評論那裏的更多細節:) – Hades