我目前有一對基於OWIN的服務,每個服務都對同一組用戶使用OAuth身份驗證。我打算隔離授權服務器(即令牌端點)並以某種方式配置我的兩個服務以接受此令牌。我認爲這將涉及我的所有服務的一些配置,以允許在所有相關服務中解密此令牌。這可能嗎?跨多個服務使用Oauth門票?
回答
Katana OAuth2授權服務器中間件並非真正爲此場景設計(主要是因爲它依賴機器密鑰進行令牌驗證)。
如果您希望集中生成令牌,那麼您應該查看專爲此設計的OAuth2授權服務器。 Thinktecture AuthorizationServer是一個開源的服務器,它可以做到這一點:http://thinktecture.github.io/Thinktecture.AuthorizationServer/
在與原帖的評論中與Brock Allen交談之後,我不能保證這是一個好的/安全的解決方案,但這是我結束的代碼使用。 (注:此代碼的版本可以a nuget package)。
我創建了一個使用AES一個IDataProtector實現:
internal class AesDataProtectorProvider : IDataProtector
{
// Fields
private byte[] key;
// Constructors
public AesDataProtectorProvider(string key)
{
using (var sha1 = new SHA256Managed())
{
this.key = sha1.ComputeHash(Encoding.UTF8.GetBytes(key));
}
}
// IDataProtector Methods
public byte[] Protect(byte[] data)
{
byte[] dataHash;
using (var sha = new SHA256Managed())
{
dataHash = sha.ComputeHash(data);
}
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = this.key;
aesAlg.GenerateIV();
using (var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV))
using (var msEncrypt = new MemoryStream())
{
msEncrypt.Write(aesAlg.IV, 0, 16);
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var bwEncrypt = new BinaryWriter(csEncrypt))
{
bwEncrypt.Write(dataHash);
bwEncrypt.Write(data.Length);
bwEncrypt.Write(data);
}
var protectedData = msEncrypt.ToArray();
return protectedData;
}
}
}
public byte[] Unprotect(byte[] protectedData)
{
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = this.key;
using (var msDecrypt = new MemoryStream(protectedData))
{
byte[] iv = new byte[16];
msDecrypt.Read(iv, 0, 16);
aesAlg.IV = iv;
using (var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV))
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
using (var brDecrypt = new BinaryReader(csDecrypt))
{
var signature = brDecrypt.ReadBytes(32);
var len = brDecrypt.ReadInt32();
var data = brDecrypt.ReadBytes(len);
byte[] dataHash;
using (var sha = new SHA256Managed())
{
dataHash = sha.ComputeHash(data);
}
if (!dataHash.SequenceEqual(signature))
throw new SecurityException("Signature does not match the computed hash");
return data;
}
}
}
}
}
,然後在ISecureDataFormat實現像這樣用的:
public class SecureTokenFormatter : ISecureDataFormat<AuthenticationTicket>
{
// Fields
private TicketSerializer serializer;
private IDataProtector protector;
private ITextEncoder encoder;
// Constructors
public SecureTokenFormatter(string key)
{
this.serializer = new TicketSerializer();
this.protector = new AesDataProtectorProvider(key);
this.encoder = TextEncodings.Base64Url;
}
// ISecureDataFormat<AuthenticationTicket> Members
public string Protect(AuthenticationTicket ticket)
{
var ticketData = this.serializer.Serialize(ticket);
var protectedData = this.protector.Protect(ticketData);
var protectedString = this.encoder.Encode(protectedData);
return protectedString;
}
public AuthenticationTicket Unprotect(string text)
{
var protectedData = this.encoder.Decode(text);
var ticketData = this.protector.Unprotect(protectedData);
var ticket = this.serializer.Deserialize(ticketData);
return ticket;
}
}
構造函數上的'key'參數可以在多個服務上設置爲相同的值,並且它們都將能夠解密('取消保護')並使用票據。
在這裏你可以找到更多的「準備好」實施AesDataProtector的:https://github.com/i4004/Owin.Security.AesDataProtectorProvider/blob/master/Owin.Security.AesDataProtectorProvider/AesDataProtector.cs – piotrwest
@piotrwest你能幫助我理解是什麼使鏈接到的實現更「準備」?我做了一個快速概述,我看到的唯一區別是注入加密工廠的能力。還有別的事嗎?在什麼情況下,我們想要注入這些工廠而不是僅僅使用這個答案中編碼的具體類? – pettys
@pettys,我應該鏈接到https://github.com/i4004/Owin.Security.AesDataProtectorProvider,它清楚地顯示了我的意圖,而不是類。通過準備,我並不意味着更好的實施/建模/設計,而是將其作爲NuGet包裝。我想我只是懶得複製和粘貼你的代碼... – piotrwest
我知道這是一個老問題,但我有一個類似的用例。根據文檔,OWIN OAuth使用機器密鑰來保護數據。由於您控制了所有實例,因此我認爲只需在Web配置中設置machinekey即可。
在這種情況下,我是在Windows服務中自託管的,除非我錯了,否則無法在app.config中設置machineKey? – Barguast
對不起,我認爲你使用的是IIS。根據我發佈的鏈接,在這種情況下,它默認使用DPAPI,它與用戶帳戶(和密碼)相關聯。在這種情況下,我認爲實施自己的數據保護器可能是您最好的選擇,但請確保您使用了衆所周知的算法。我不知道你在哪裏找到你的,所以我不會保證它是相對安全的,但它似乎是一個好的開始。 – jbblanchet
謝謝,它在過去的幾個月裏一直在使用,它的功能非常好。 – Barguast
你可以使用這個NuGet包https://www.nuget.org/packages/Owin.Security.AesDataProtectorProvider/
它包含IAppBuilder擴展方法,可以讓你建立自己的關鍵
appBuilder.UseAesDataProtectorProvider(key);
- 1. CAS服務器跨子域ST票
- 2. windows XP和unix中kerberos門票TGT和服務門票的路徑?
- 3. OpenStaxk:使用CPU跨多臺服務器
- 4. 多張門票Java彩票計劃
- 5. 如何安全使用OAuth 2.0的多個資源服務器?
- 6. 跨多個網站收集投票
- 7. 服務層模式:跨越多個服務的業務邏輯
- 8. 跨多個服務器合併數據
- 9. 跨多個網絡服務交易
- 10. SOA:跨多個服務加入數據
- 11. 獲取門票
- 12. Tableau門票 - POST獲取門票返回登錄表單,而不是門票ID
- 13. 如何通過JIRA中的門票名稱和門票號碼訂購門票?
- 14. Codeigniter + oAuth服務
- 15. 使用多個QNA服務
- 16. 投票使用Ajax和Dojo服務器
- 17. SQL服務器2008R2 JavaKerberos不承認Krb5LoginModule門票
- 18. 使用linq按門票未關閉的最低日期訂購門票?
- 19. 可以使用oAuth 2.0服務器代替oAuth 1.0服務器嗎?
- 20. 自助服務門戶/ PaaS使用Yesod
- 21. Oauth在Appengine上使用Google Play服務
- 22. Facebook使用OAuth服務器端註銷
- 23. 使用Twitter的服務認證Oauth
- 24. 使用oauth保護SOAP Web服務
- 25. 幫助使用Twitter/OAuth入門
- 26. 如何使用跨多個服務器鏈接的過程的事務?
- 27. 投票服務 - C#
- 28. 使用SAML的CAS服務器和服務票據
- 29. 我可以使用OAuth將我的用戶登錄到多個服務嗎?
- 30. 無法從門票
我其實是有一些運氣與此發佈之後。在服務器配置和承載令牌配置上都有一個AccessTokenFormat屬性。我實現了ISecureDataFormat來序列化票證並用AES加密。假設我爲我的所有服務使用相同的密碼密鑰,令牌似乎對其中的每個服務都起作用。你看到這個方法有什麼問題嗎?如果沒有,我會寫出一個正確的答案。感謝您的回覆。 –
Barguast
可擴展性點當然在那裏,所以這是可能的。只是不幸的是,他們把這一切留給了一般開發人員來填補這些。這就是爲什麼它不幸 - 你不需要加密(本身),但你想要一個簽名來驗證它是從你的服務器。成功的解密不提供信任。 –
謝謝,儘管我很努力地想知道爲什麼我的方法可能有害。它只是在DPAPI上使用AES,並且在那裏有簽名檢查元素以確保無效但可解密的標記仍然被拒絕。 – Barguast