2

私は、実際には完全なSAML応答XMLドキュメントであるBase64でエンコードされた文字列を返すWCFサービスに取り組んでいます。この情報はベンダーに渡されるため、SAMLドキュメントの外観とエンコード方法に関するベンダーの要件を満たす必要があります。要件を満たす出力を取得できません。

WCFとWIFが一緒に役立つはずです。私は当初、WIFを使用してサービスを構築し、SAMLアサーション(トークン)とその他のC#コードを作成して、最終的なSAMLドキュメントを生成しました。ドキュメントの<EncryptedData>ノードを除いて、これらはすべて機能し、ベンダーの要件を満たしています。このセクションではAES256とRSAOAEPを使用していますが、ベンダーはAES128とRSA15を望んでいます。したがって、私は解決策を探しています。どんな助けでも大歓迎です。

これがウォークスルーです。

このサービスは、データベースを呼び出してフィールドを返すために使用されるGUIDを受け取ります。これらは次のように使用されます。

DataTable userData = GetDataForUser(userId);
List<Claim> claims = new List<Claim>()
{
    new Claim("ClientId", "NameOfClient")
};
foreach (DataRow row in userData.Rows)
{
    string memberId = row["MemberId"].ToString().Trim();
    string firstName = row["FirstName"].ToString().Trim();
    string lastName = row["LastName"].ToString().Trim();
    DateTime dob = Convert.ToDateTime(row["DateOfBirth"], CultureInfo.InvariantCulture);

    claims.Add(new Claim("MemberId", memberId));
    claims.Add(new Claim("FirstName", firstName));
    claims.Add(new Claim("LastName", lastName));
    claims.Add(new Claim("DOB", dob.ToString("MM/dd/yyyy")));
}

return claims;

次に、次のようなSecurityTokenDescriptorを作成します。

SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor();

クレームは次のように記述子に追加されます。

descriptor.Subject = new ClaimsIdentity(claims);

記述子は、次のようにトークンを暗号化するように指示されます。

descriptor.EncryptingCredentials = GetEncryptingCredentials();

GetEncryptingCredentials()ルーチンは次のようになります。

private EncryptedKeyEncryptingCredentials GetEncryptingCredentials()
{
    // Get the Encrypting Certificate
    X509Certificate2 encryptCert = CertificateHelper.FindSingleCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, X509FindType.FindBySubjectDistinguishedName, "<<certificate stuff here >>", true);

    EncryptedKeyEncryptingCredentials encryptingCreds = new EncryptedKeyEncryptingCredentials(encryptCert);

    return encryptingCreds;
 }

これらすべてがトークンを生成し、ファイルに書き込むと次のようになります。

  <EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
    <xenc:EncryptedData Id="_16584ace-9f3e-4352-9fc9-f6db8b2e925c" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
      <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
          <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          </e:EncryptionMethod>
          <KeyInfo>
            <o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
              <X509Data>
                <X509IssuerSerial>
                  <X509IssuerName><!-- value --></X509IssuerName>
                  <X509SerialNumber><!-- value --></X509SerialNumber>
                </X509IssuerSerial>
              </X509Data>
            </o:SecurityTokenReference>
          </KeyInfo>
          <e:CipherData>
            <e:CipherValue><!-- value -->CipherValue>
          </e:CipherData>
        </e:EncryptedKey>
      </KeyInfo>
      <xenc:CipherData><xenc:CipherValue><!-- value --></xenc:CipherValue>
      </xenc:CipherData>
    </xenc:EncryptedData>
  </EncryptedAssertion>

素晴らしいですよね?いいえ。ベンダーは、次の子ノードを持つために<EncryptedData>セクションを必要とします。

<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>

そして、これを表示するには、<KeyInfo><EncryptedKey>セクションが必要です。

<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>

GetEncryptingCredentials()ルーチン内で考えられるすべての組み合わせを試しました。望ましい結果が得られたものはありません。私が受け取る最も有望なエラーメッセージは次のようになります。

ID4178:SecurityTokenDescriptorで提供されるEncryptingCredentialsは、非対称キー用です。トークンを暗号化するには、EncryptedKeyEncryptingCredentialsを使用する必要があります。

誰か提案がありますか?最初からやり直すように言ってください。大丈夫です。これを機能させる必要があります。

前もって感謝します。

4

1 に答える 1

6

私はうまくいく解決策を見つけました。少なくとも、必要に応じてXMLを生成し、ベンダーは、私が送信しているものを使用できると言っています。

GetEncryptingCredentials()ルーチンを少し書き直しました。これで、次のようになります。

private EncryptingCredentials GetEncryptingCredentials()
{
    string keyWrapAlgorithm = SecurityAlgorithms.RsaV15KeyWrap; //"http://www.w3.org/2001/04/xmlenc#aes256-cbc";
    string encryptionAlgorithm = SecurityAlgorithms.Aes128Encryption; //"http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p";
    int keySize = 128;

    X509Certificate2 encryptCert = CertificateHelper.FindSingleCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, X509FindType.FindBySubjectDistinguishedName, _settings.EncryptingCredentials, true);

    EncryptingCredentials encryptingCredentials = new EncryptedKeyEncryptingCredentials(encryptCert, keyWrapAlgorithm, keySize, encryptionAlgorithm);

    return encryptingCredentials;
}

みんなに知らせて、これに関するループを閉じると思っただけです。

于 2010-11-17T13:26:18.727 に答える