「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。 目次 †概要 †汎用認証サイトにSAML2.0を実装するため作成。 スコープ †SAMLの仕様は膨大だが、使われていないものも多い。 Profile †
Binding †
Core †
メタデータ †
トラストサークル †
署名 †前述のトラストサークルの慣例から、リクエスト・レスポンス共に署名を行う。 スコープ外 †Web Browser SSO 以外の Profile †SAMLは、Web Browser SSO Profile以外で使われていない。 HTTP Artifact Binding †IdM実験室によると...。 昔はデータサイズの問題で、Artifact Binding を使っていたが
ただ、今でも稀にArtifact Binding しか使えないSPが
詳細 †プロトコル&アサーション †AuthnRequest? †
Assertion †例を参考にする。 Response †例を参考にする。 エンコード・デコード †下記のsamltool.ioからアサーションを取得し、SAMLTool.comで確認するなど。 HTTP Redirect Binding †HTTP POST Binding †署名・検証のポイント †ネストした複数のXML署名が Verify できない †SignedXml?クラスの実装に問題があり、
※ 外側だけ検証すればイイ気がする。 Whitespace を保持したままのXML署名が Verify できない †XmlDocuement? を利用する際に PreserveWhitespace? を単に true にする。 SAML v2 schema(XSD) による SAML(XML) の検証 †以下を用いて、SAMLを検証する。
しかし、結局XPathで検証していたりする。 SAMLTool.com(エンコード・デコード、署名・検証) †NameIDFormat †SAML Assertionsに指定する。 unspecified †既定値(ユーザ名) entity †UserId?(Public UserID) emailAddress †メアド persistent †UserId?(Pairwise UserID) AttributeValue? †様々なクレームを指定可能 †様々なクレームを、 に指定できる。 AD FSの実装例 †この設定は、Custom Claim Rule(要求規則)に設定するらしい 登録情報 †IdP/STS側 †
Client側 †
SAMLのテスト †例 †シーケンス(Artifact無し) †Technical Overviewから取り出したサンプル・シーケンス リクエスト †
レスポンス †
アサーション †<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="identifier_2" InResponseTo="identifier_1" Version="2.0" IssueInstant="2004-12-05T09:22:05Z" Destination="https://sp.example.com/SAML2/SSO/POST"> <saml:Issuer> https://idp.example.org/SAML2 </saml:Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="identifier_3" Version="2.0" IssueInstant="2004-12-05T09:22:05Z"> <saml:Issuer> https://idp.example.org/SAML2 </saml:Issuer> <!-- a POSTed assertion MUST be signed --> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> ... </ds:Signature> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"> 3f7b3dcf-1674-4ecd-92c8-1544f346baf8 </saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData InResponseTo="identifier_1" NotOnOrAfter="2004-12-05T09:27:05Z" Recipient="https://sp.example.com/SAML2/SSO/POST"/> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2004-12-05T09:17:05Z" NotOnOrAfter="2004-12-05T09:27:05Z"> <saml:AudienceRestriction> <saml:Audience> https://sp.example.com/SAML2 </saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2004-12-05T09:22:00Z" SessionIndex="identifier_3"> <saml:AuthnContext> <saml:AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport </saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> </saml:Assertion> </samlp:Response> シーケンス(Artifact有り) †医療分野共通認証基盤整備コンソーシアムのドキュメントから取り出したサンプル・シーケンス リクエスト1 †
レスポンス1 †
リクエスト2 †Artifact Binding POST /SAML/Artifact/Resolve HTTP/1.1 HOST: IdentityProvider.com Content-Type: text/xml Content-Length: nnn SOAPAction: http://www.oasis-open.org/committees/security <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <samlp:ArtifactResolve xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="_6c3a4f8b9c2d" Version="2.0" IssueInstant="2004-01-21T19:00:49Z"> <Issuer>https://ServiceProvider.com/SAML/</Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...Signature...</ds:Signature> <Artifact>...artifact...</Artifact> </samlp:ArtifactResolve> </SOAP-ENV:Body> </SOAP-ENV:Envelope> レスポンス2 †Artifact Binding HTTP/1.1 200 OK Date: 21 Jan 2004 07:00:49 GMT Content-Type: application/soap+xml Content-Length: nnnn <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <samlp:ArtifactResponse xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="identifier_3" InResponseTo="identifier_2" Version="2.0" IssueInstant="2004-12-05T09:22:05Z"> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="identifier_4" InResponseTo="identifier_1" Version="2.0" IssueInstant="2004-12-05T09:22:05Z" Destination="https://ServiceProvider.com/SAML/SSO/Artifact"> <saml:Issuer> medical-doctor-sso-idp </saml:Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <saml:Assertion ... </saml:Assertion> </samlp:Response> </samlp:ArtifactResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope> アサーション †<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="s2ead62f287a9e36c31b3a693974582fdae20c5351" IssueInstant="2011-06-28T05:08:41Z"> <saml:Issuer> medical-doctor-sso-idp </saml:Issuer> <saml:Subject> <saml:NameID NameQualifier="medical-doctor-sso-idp" SPNameQualifier="sso-sp" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"> 1234567890 </saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData InResponseTo="s2cee63177ff33bcacd5263caa4af9da101837de24" NotOnOrAfter="2011-06-28T05:18:41Z" Recipient="https://ServiceProvider.com/SAML/Consumer/metaAlias/sp"> </saml:SubjectConfirmationData> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2011-06-28T04:58:41Z" NotOnOrAfter="2011-06-28T05:18:41Z"> <saml:AudienceRestriction> <saml:Audience> sso-sp </saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2011-06-28T05:08:41Z" SessionIndex="xxxxx"> <saml:AuthnContext> <saml:AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:X509 </saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> <saml:AttributeStatement> <saml:Attribute Name="HCROLE "> <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string"> Medical Doctor </saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> </saml:Assertion> シーケンス(Azure AD) †リクエスト †<samlp:AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:metadata" ID="id6c1c178c166d486687be4aaf5e482730" Version="2.0" IssueInstant="2013-03-18T03:28:54.1839884Z" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://www.contoso.com</Issuer> <NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/> </samlp:AuthnRequest> レスポンス †<samlp:Response ID="_a4958bfd-e107-4e67-b06d-0d85ade2e76a" Version="2.0" IssueInstant="2013-03-18T07:38:15.144Z" Destination="https://contoso.com/identity/inboundsso.aspx" InResponseTo="id758d0ef385634593a77bdf7e632984b6" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> https://login.microsoftonline.com/82869000-6ad1-48f0-8171-272ed18796e9/ </Issuer> <ds:Signature xmlns:ds="https://www.w3.org/2000/09/xmldsig#"> ... </ds:Signature> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /> </samlp:Status> <Assertion ... </Assertion> </samlp:Response> アサーション †<Assertion ID="_bf9c623d-cc20-407a-9a59-c2d0aee84d12" Version="2.0" IssueInstant="2013-03-18T07:38:15.144Z" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> <Issuer>https://login.microsoftonline.com/82869000-6ad1-48f0-8171-272ed18796e9/</Issuer> <ds:Signature xmlns:ds="https://www.w3.org/2000/09/xmldsig#"> ... </ds:Signature> <Subject> <NameID>Uz2Pqz1X7pxe4XLWxV9KJQ+n59d573SepSAkuYKSde8=</NameID> <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <SubjectConfirmationData InResponseTo="id758d0ef385634593a77bdf7e632984b6" NotOnOrAfter="2013-03-18T07:43:15.144Z" Recipient="https://contoso.com/identity/inboundsso.aspx" /> </SubjectConfirmation> </Subject> <Conditions NotBefore="2013-03-18T07:38:15.128Z" NotOnOrAfter="2013-03-18T08:48:15.128Z"> <AudienceRestriction> <Audience>https://www.contoso.com</Audience> </AudienceRestriction> </Conditions> <AttributeStatement> <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"> <AttributeValue>testuser@contoso.com</AttributeValue> </Attribute> <Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier"> <AttributeValue>3F2504E0-4F89-11D3-9A0C-0305E82C3301</AttributeValue> </Attribute> ... </AttributeStatement> <AuthnStatement AuthnInstant="2013-03-18T07:33:56.000Z" SessionIndex="_bf9c623d-cc20-407a-9a59-c2d0aee84d12"> <AuthnContext> <AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:Password </AuthnContextClassRef> </AuthnContext> </AuthnStatement> </Assertion> シーケンス(Cybozu) †リクエスト †<samlp:AuthnRequest AssertionConsumerServiceURL="https://(sub_domain).cybozu.com/saml/acs" ID="szqd0c3d0u3vpz5jwna4p24iso42opc4" IssueInstant="2013-04-01T00:00:00Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> https://(sub_domain).cybozu.com </saml:Issuer> <samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" /> </samlp:AuthnRequest> レスポンス †<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="s2b39863179da0358f10bb499d6ac0e64062e89e1d" InResponseTo="szqd0c3d0u3vpz5jwna4p24iso42opc4" Version="2.0" IssueInstant="2013-04-01T00:30:00Z" Destination="https://(sub_domain).cybozu.com/saml/acs"> <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> http://(idp_host) </saml:Issuer> <samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> <samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <saml:Assertion ... </saml:Assertion> </samlp:Response> アサーション †<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="s2822cac48e7b7ec82ff36710996423e7baec43a00" IssueInstant="2013-04-01T00:30:00Z" Version="2.0"> <saml:Issuer> https://(idp_host) </saml:Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> ...アサーションの署名の内容... </ds:Signature> <saml:Subject> <saml:NameID NameQualifier="https://(idp_host)" SPNameQualifier="https://(sub_domain).cybozu.com" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"> watanabe </saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData InResponseTo="szqd0c3d0u3vpz5jwna4p24iso42opc4" NotOnOrAfter="2013-04-01T00:40:00Z" Recipient="https://(sub_domain).cybozu.com/saml/acs" /> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2013-04-01T00:20:00Z" NotOnOrAfter="2013-04-01T00:40:00Z"> <saml:AudienceRestriction> <saml:Audience>https://(sub_domain).cybozu.com </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2013-04-01T00:29:30Z" SessionIndex="s2901e6c0e0cc0c8f1aa1075215125b2676774dd01"> <saml:AuthnContext> <saml:AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport </saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> </saml:Assertion> 参考 †
XML署名・暗号 †IdM実験室 †
OneLogin? †developers.onelogin.com †
SAMLTool.com †
Sustainsys/Saml2 †GitHub †
NuGet †
SignedXml?での署名・検証の問題対策 †
SAMLの実装を検証する。 †Tags: :IT国際標準, :認証基盤, :クレームベース認証, :SAML |