簡體   English   中英

如何在.Net 中解析 SAML 斷言請求

[英]How to parse a SAML assertion request in .Net

我正在嘗試在.Net 中實現 SAML SSO 解決方案,但在解析斷言時遇到問題。

我有一個示例斷言(看起來像byte[]數據作為文本)和相應的.p7b文件。

我想從.p7b加載密鑰並將斷言解密為 XML 文檔。

到目前為止,我認為我正在正確讀取密鑰:

// get the key data
byte[] certificateData = System.IO.File.ReadAllBytes("myKeys.p7b");

// decode the keys
var cms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber);
cms.Decode(certificateData);

var samlCertificates = cms.Certificates;

然后我嘗試解析我遇到問題的斷言:

// we have a keychain of X509Certificate2s, we need a collection of tokens
var certificatesAsTokens =
    from X509Certificate2 cert in samlCertificates
    select new X509SecurityToken(cert) as SecurityToken;

// get a token resolver
var tokens = new ReadOnlyCollection<SecurityToken>(
    certificatesAsTokens.ToList());
var resolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
    tokens, true);

// get the SAML data in an XML reader
var reader = XmlReader.Create(assertionPostStream);

// use the WS Security stuff to parse the reader
var securityToken = WSSecurityTokenSerializer.
    DefaultInstance.ReadToken(reader, resolver) as SamlSecurityToken;

最后一條語句引發異常,指出它無法解析 XML 內容。

我認為這意味着我錯過了解密斷言的步驟 - 將byte[]作為文本轉換為 SAML 格式 XML 文檔。

有人知道如何添加此步驟嗎? 我還缺少其他東西嗎?

我已經弄明白了 - 我錯過了SAML規范的一部分。

斷言被發送(相當奇怪,因為它沒有加密)作為base64數據,並且它被發送的URL編碼兩次。

所以添加這個步驟給了我們一個有效的斷言:

// spec says "SAMLResponse=" 
string rawSamlData = Request["SAMLResponse"];

// the sample data sent us may be already encoded, 
// which results in double encoding
if (rawSamlData.Contains('%'))
{
    rawSamlData = HttpUtility.UrlDecode(rawSamlData);
}

// read the base64 encoded bytes
byte[] samlData = Convert.FromBase64String(rawSamlData);

// read back into a UTF string
string samlAssertion = Encoding.UTF8.GetString(samlData);

身份驗證仍然無法正常工作 ,但我現在擁有有效的XML,因此這是一個不同的問題。

這是我的工作源代碼:

            byte[] samlData = Convert.FromBase64String(samlresponse);

            var decompressedStream = SAMLUtility.Decompress(samlData);
            StreamReader reader = new StreamReader(decompressedStream);
            var decodedSaml = reader.ReadToEnd();

            var serializer = new XmlSerializer(typeof(Response));
            Response samlResponse;

            using (TextReader reader1 = new StringReader(decodedSaml))
            {
                samlResponse = (Response)serializer.Deserialize(reader1);
            }

            if (samlResponse.Status.StatusCode.Value.Contains("Success"))
                return samlResponse;
            else
                return null;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM