会社のWebサイトの(依存パーティとして)SAMLでSSOを実装する必要があります。もちろん重要な部分は、署名の検証です。パートナー企業(アサーティングパーティ)からのサンプルSAMLの署名部分は次のとおりです。
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
<ds:Reference URI="#_2152811999472b94a0e9644dbc932cc3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:Transforms xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ec:InclusiveNamespaces PrefixList="ds saml samlp xs" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
<ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">bW1Os7+WykqRt5h0mdv9o3ZF0JI=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
cgrAN4T/UmobhrkkTi3miiRfbo0Z7aakSZjXuTWlZlu9jDptxPNbOFw8ZbYKZYyuW544wQqgqpnG
gr5GBWILSngURjf2N45/GDv7HMrv/NRMsRMrgVfFsKbcAovQdLAs24O0Q9CH5UdADai1QtDro3jx
nl4x7HaWIo9F8Gp/H1c=
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIElzCCA3+gAwIBAgIQNT2i6HKJtCXFUFRB8qYsZjANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQG
EwJGUjEOMAwGA1UEBxMFUGFyaXMxDDAKBgNVBAoTA3BzYTEgMB4GA1UECxMXY2VydGlmaWNhdGUg
YXV0aG9yaXRpZXMxKDAmBgNVBAMTH0FDIFBTQSBQZXVnZW90IENpdHJvZW4gUHJvZ3JhbXMwHhcN
MDkwODE5MDcxNTE4WhcNMTEwODE5MDcxNTE5WjCBhjELMAkGA1UEBhMCZnIxHzAdBgkqhkiG9w0B
CQEWEHBhc3NleHRAbXBzYS5jb20xGDAWBgoJkiaJk/IsZAEBEwhtZGVtb2IwMDEMMAoGA1UEChMD
cHNhMREwDwYDVQQLEwhwcm9ncmFtczEbMBkGA1UEAxMSVGVzdCAtIFBBU1NFWFQgREVWMIGfMA0G
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuY1nrepgACvDSTLWk5A1cFOJSwDbl6CWfYp3cNYR0K3YV
e07MDZn+Rv4jo3SusHVFds+mzKX2f8AeZjkA3Me/0yiS9UpS9LQZu9mnhFlZRhmUlDDoIZxovLXN
aOv/YHmPeTQMQmJZu5TjqraUq7La1c187AoJuNfpxt227N1vOQIDAQABo4IBkTCCAY0wDgYDVR0P
AQH/BAQDAgWgMB8GA1UdIwQYMBaAFLceWtTfVeRuVCTDQWkmwO4U01X/MAwGA1UdEwEB/wQCMAAw
gbYGA1UdIASBrjCBqzCBqAYKKoF6ARfOEAEBBDCBmTBBBggrBgEFBQcCARY1aHR0cDovL3JldW5p
cy5pbmV0cHNhLmNvbS9hdXRvcml0ZS9QQy1BQy1Qcm9ncmFtcy5wZGYwVAYIKwYBBQUHAgIwSDAK
FgNwc2EwAwIBARo6UG9saXRpcXVlIGRlIENlcnRpZmljYXRpb24gQUMgUFNBIFBldWdlb3QgQ2l0
cm9lbiBQcm9ncmFtczBcBgNVHR8EVTBTMFGgT6BNhktodHRwOi8vaW5mb2NlcnQucHNhLXBldWdl
b3QtY2l0cm9lbi5jb20vQUMtUFNBLVBldWdlb3QtQ2l0cm9lbi1Qcm9ncmFtcy5jcmwwHQYDVR0l
BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBYGA1UdDgQPBA1BVVRPX0dFTkVSQVRFMA0GCSqGSIb3
DQEBBQUAA4IBAQCvRtP6bFkOUEHcqc6yUX0Q1Gk2WaAcx4ziUB0tw2GR9I0276JRJR0EGuJ/N6Fn
3FhLQrSPmS97Xvc9XmiI66fQUdg64g9YqBecdiQlUkR20VLgI6Nq8pldQlWjU2iYlkP15U7VF4Qr
0Pb2QiIljZUCKdv3qdED2Ri33za46LfykrlwZB0uhTVUxI/AEtjkKVFaZaqanJg+vJyZI5b30z7g
Ff8L3ht4Z7SFKdmY3IQSGzElIAAUfduzTJX0cwnGSU9D4BJu1BS8hWnYPwhk+nBJ7OFhXdwYQFWq
fhpBLq+ciJti9OMhcdCSIi0PbrOqzqtX7hZUQOvfShhCTJnl5TJJ</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
私が理解していないのは、証明書が署名内にあるのはなぜですか?
私は通常、安全な方法で会社から証明書を取得することを意味するので、証明書は彼らからのものであることを知っています。そして、署名の検証が成功すると、パートナー企業が署名したことを知っています。
しかし、証明書がSAML-Responseの署名内にある場合、だれでも送信できます。私が知っている唯一のことは、応答が改ざんされていないことです。しかし、ポイントは、誰がSAMLを送信したのかわからないということです。
誰も私に説明できますか、それがどのように機能するのですか?
SAML応答には、署名とその署名の公開キーが付属しています。
公開キーを使用して、SAMLレスポンスのコンテンツがキーと一致することを確認できます。つまり、そのレスポンスは、メッセージ内の公開キーと一致するプライベートキーを持つ人から間違いなく送信されたものであり、改ざん。
どの技術を使用しているのかわかりませんが、.Netでは次のように確認できます。
// load a new XML document
var assertion = new XmlDocument { PreserveWhitespace = true };
assertion.LoadXml("The SAML XML that you were sent");
// use a namespace manager to avoid the worst of xpaths
var ns = new XmlNamespaceManager(assertion.NameTable);
ns.AddNamespace("samlp", @"urn:oasis:names:tc:SAML:2.0:protocol");
ns.AddNamespace("asrt", @"urn:oasis:names:tc:SAML:2.0:assertion");
ns.AddNamespace("dsig", @"http://www.w3.org/2000/09/xmldsig#");
// get nodes down to the signature
var responseNode = assertion.SelectSingleNode("/samlp:Response", ns);
var assertionNode = responseNode.SelectSingleNode("asrt:Assertion", ns);
var signNode = assertionNode.SelectSingleNode("dsig:Signature", ns);
// load the XML signature
var signedXml = new SignedXml(assertion.DocumentElement);
signedXml.LoadXml(signNode as XmlElement);
// get the certificate, basically:
// signedXml.KeyInfo[0].Certificates[0]
// ...but with added casting
var certificate = GetFirstX509Certificate(signedXml);
// check the key and signature match
bool isSigned = signedXml.CheckSignature(certificate, true);
これは、メッセージがそれが言う人からのものであることをチェックするだけです。信頼できる誰かからメッセージが来たという追加のチェックが必要です。このチェックはより低速です-失効を含める必要があり、証明書のチェーン全体を検証する必要がある場合があります。
通常、これは、SAML応答を受け入れる公開キーのリストになります。
次に、このメッセージが改ざんされていないこと、および信頼できる誰かからのものであることを確認できます。したがって、提供されたSAML属性で提供されたユーザーの詳細を承認できます。
couldはすでに公開キーを持っているため、署名に公開キーを再度含める必要はありませんが、複数の既知の送信者、または既知の送信者のチェーンを含めることもできます。
たとえば、2つの信頼できるプロバイダーがある場合があります。どちらの場合でも、どちらかのプロバイダーを信頼するかどうかを確認する前に、メッセージが改ざんされていないことを確認します。キーが署名にない場合、アサーションは少し小さくなりますが、アサーションがどのIDプロバイダーからのものであるかを事前に知る必要があります。
そのため、公開鍵が署名に含まれる主な理由は2つあります。
キーが指定される理由は、IDプロバイダーのメタデータが複数の署名キーを指定でき、署名に含めることで使用するキーを指定できるためです。 SAML 2.0では、Assertion
でキーが指定されていない場合、コンテキストによって(アサーティングパーティのメタデータから)推測できることが必要です。
たとえば、アサーティングパーティのメタデータにこれがある場合があります。
<KeyDescriptor>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
BQUAMCMxITAfBgNVBAMTGGlkcDEudGFuZ29oZWFsdGhkZW1vLmNvbTAeFw0xMzA1
...snip...
ttHq2Wi5J7img1M2zo28hH5DK78S+XerfXHK2HEZYZs=
</ds:X509Certificate>
</ds:X509Data>
<ds:X509Data>
<ds:X509Certificate>
H24a88h7zlq+pnAxQm0CAwEAAaN3MHUwVAYDVR0RBE0wS4IYaWRwMS50YW5nb2hl
...snip...
mg1M2zo28hH5DK78=
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
署名される各XML要素は、署名に使用されるキーを指定できます。ただし、SAML 2.0の場合、その署名キーは(たとえば)署名を生成するパーティのメタデータで定義されているものと一致する必要があります。署名とともに提供されたキーが信頼されていない場合(この場合、メタデータで指定されていない場合)、SAMLシステムは署名の検証時にエラーを生成する必要があります。
署名証明書の公開部分はSAMLメッセージにあります。これは、トークン自体の署名を確認するために使用され、もちろん、受信者がトークンを発行した人を識別し、それに応じて処理できるようにします。
そこにあるという事実は、XMLデジタル署名仕様の一部であり、実際にはSAML固有のものではありません。証明書がなければ、トークンの出所をどのように確認でき、どのように検証できますか?
XmlDSigは他の方法を指定します。サブジェクト、シリアル番号、ハッシュなどによって署名キーを識別できますが、これは受信側が公開証明書を持っていることを前提としています。 SAMLの場合、これは当てはまらない可能性があるため、X509証明書の公開部分を埋め込みます。
投稿はかなり遅れましたが、SAMLで作業しなければならず、これらのドキュメントを見つけました。 SAMLについての優れた洞察を提供します。SAMLがどのように機能し、どのパラメーターが期待されるかを示しています。 SAMLを初めて使用する他の人の助けになるはずです。
http://developers.onelogin.com/v1.0/page/intro-to-onelogins-open-source-saml-toolkits
http://developers.onelogin.com/v1.0/page/saml-toolkit-for-Ruby-on-Rails