「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>SAMLの仕様を読む。]] * 目次 [#b2a7541f] #contents *概要 [#ifcd76fe] [[汎用認証サイト>https://opentouryo.osscons.jp/index.php?%E6%B1%8E%E7%94%A8%E8%AA%8D%E8%A8%BC%E3%82%B5%E3%82%A4%E3%83%88%EF%BC%88Multi-purpose%20Authentication%20Site%EF%BC%89]]にSAML2.0を実装するため作成中。 **スコープ [#c3c6d2ee] SAMLの仕様は膨大だが、使われていないものも多い。~ 以下の範囲に絞れば、実装は割とスリムになる。 ***Profile [#p687a1ad] -SP Initiated な Web Browser SSO Profile -Federation Using Out-of-Band Account Linking ***Binding [#td5a6e06] -Authentication Request~ HTTP Redirect Binding -Authentication Response~ HTTP POST Binding ***Core [#o17d59b6] -Protocols~ Authentication Request Protocol ***メタデータ [#lae5de8c] -SP側はメタデータを公開しない。 -IdP側はメタデータを公開する。 --メタデータは仕様提示と設定入力支援にのみ使用する。 --メタデータで指定された範囲の仕様で応答する(一意になるオプションは不要)。 --[[SAML Metadata]]で、[[AuthnRequest>#o17d59b6]]に指定可能な内容を示す。 ***トラストサークル [#n3f3080b] -[[仕様上>SAMLの仕様を読む。#t41413c4]]、トラストサークルと言う用語は出てこない。 -単純に「&color(red){IdP-SP 間で、お互いを事前に登録し、お互いの証明書を交換する。};」こと。 -ただ、Azure ADやCybozuの仕様を見ると、Requestに署名しているケースは限られている~ (イントラからのフェデレーションではRequestにも署名しているものと思われる)。 ***署名 [#rea338f3] 前述の[[トラストサークル>#n3f3080b]]の慣例から、リクエスト・レスポンス共に署名を行う。 **スコープ外 [#q78031b1] ***Web Browser SSO 以外の Profile [#qf80e00b] SAMLは、Web Browser SSO Profile以外で使われていない。 ***HTTP Artifact Binding [#eddf5dd5] IdM実験室によると...。 昔はデータサイズの問題で、Artifact Binding を使っていたが~ 最近は通信速度や端末性能の向上により、使われることは減ってきているらしい。 >SPとIdPの間で直接通信をさせなければならないので、~ クラウドサービスと社内IdPを連携させる場合など面倒なため。 ただ、今でも稀にArtifact Binding しか使えないSPが~ 存在するので、仕方なく(IdP側に)実装することがある。 >なお、AD FSではArtifact Binding をサポートしている。~ Azure ADはPOST BindingのみでArtifact Binding は使えない。 *詳細 [#pacd686c] **プロトコル&アサーション [#w4e8373f] ***AuthnRequest [#hbfed6bc] -NameIDPolicy --Format~ ○ unspecified ○ entity ○ emailAddress ☓ persistent(永続的仮名) ☓ transient(一時的仮名) ☓☓ X509SubjectName ☓☓ WindowsDomainQualifiedName ☓☓ kerberos --AllowCreate="false" -RequestedAuthnContext~ 多くのSPでは使用していない --Comparison属性 ○ exact ☓ minimum ☓ maximum ☓ better --AuthnContextClassRef要素~ [[urn:oasis:names:tc:SAML:2.0:ac:classes>SAMLの仕様を読む。#fcb8eb3c]] ○ unspecified(不特定の方法で) ○ PasswordProtectedTransport(パスワード) ☓ Password(PasswordProtectedTransportとの違いが?) ☓ PreviousSession(既存のセッションを利用) ☓ X509 ☓ SecureRemotePassword ☓ TimeSyncToken ☓ Smartcard ☓ SmartcardPKI ☓ MobileOneFactorContract ☓ MobileOneFactorUnregistered ☓ MobileTwoFactorContract ☓ MobileTwoFactorUnregistered ☓ PGP ☓ SPKI ☓ XMLDSig ☓ TLSClient ☓ Kerberos ☓ Telephony ☓ NomadTelephony ☓ AuthenticatedTelephony ☓ SoftwarePKI ☓ InternetProtocol ☓ PersonalTelephony ☓ InternetProtocolPassword ***Assertion [#ob20babf] [[例>#d22e55c7]]を参考にする。 ***Response [#t47ab309] [[例>#d22e55c7]]を参考にする。 **エンコード・デコード [#n9b349a2] 下記の[[samltool.io>#q968ebd8]]からアサーションを取得し、[[SAMLTool.com>#ne63aadb]]で確認するなど。 ***[[HTTP Redirect Binding>SAML Bindings#h2a04080]] [#tb6af859] ***[[HTTP POST Binding>SAML Bindings#r153e192]] [#vee58a36] **署名・検証のポイント [#f681a495] ***ネストした複数のXML署名が Verify できない [#k3724cb3] SignedXmlクラスの実装に問題があり、~ ネストした複数のXML署名が Verify できないという問題があるらしい。 -SAMLはAssertion 側と Response 側どちらでの Signature の存在を仕様上は認めている。 -そのためIdP(またはその設定)によっては両方にXML署名が存在する場合がある。 -ネストしている場合の正規化では、外側のSignatureを取り除き、内部は残しておく。 -System.Security.Cryptography.SignedXmlクラスの実装に問題がある。~ (ネストした Signature を扱うと Verify できないバグがある) ※ 外側だけ検証すればイイ気がする。~ [[コチラ>#i172c117]]が、SignedXmlによるネストしたXML署名・検証結果。 ***Whitespace を保持したままのXML署名が Verify できない [#n4ce6eeb] XmlDocuement を利用する際に PreserveWhitespace を単に true にする。 ***SAML v2 schema(XSD) による SAML(XML) の検証 [#d166fa72] 以下を用いて、SAMLを検証する。 -SAML v2 schema - Oasis --https://docs.oasis-open.org/security/saml/v2.0/saml-schema-protocol-2.0.xsd --https://docs.oasis-open.org/security/saml/v2.0/saml-schema-assertion-2.0.xsd -[[XML Schemaによる検証>XML#m4dab3f5]] しかし、結局XPathで検証していたりする。~ (適切な、ミニマムのXSDをオンラインで発見できないため) ***[[SAMLTool.com>#ne63aadb]](エンコード・デコード、署名・検証) [#g3e380c9] **[[NameIDFormat>SAML Core#wf653d3e]] [#e0f28632] ***unspecified [#ef6434a7] 既定値 ***entity [#s3c734a2] UserId、UserNameなど。 ***emailAddress [#x22f87c7] メアド **AttributeValue [#hbf751d3] ***様々なクレームを指定可能 [#e3f79605] 様々なクレームを、 >AttributeStatement > Attribute > AttributeValue に指定できる。 ***AD FSの実装例 [#m36d6faf] この設定は、Custom Claim Rule(要求規則)に設定するらしい~ (samlp:AuthnRequestに要求を設定するという方式では無さそう)。 **登録情報 [#k6695911] ***IdP/STS側 [#qfca7d97] -新規追加 --NameIDFormat~ --SAMLResponseエンドポイント~ AssertionConsumerServiceとも呼ばれ、~ OAuthのコンテキストではredirect_uriに相当する。 -OAuth2/OIDCインフラを流用 --Isser(client_idを流用) --Clientの公開鍵 ***Client側 [#h3a7568b] -新規追加~ なし -OAuth2/OIDCインフラを流用 --IdPの公開鍵 -対応不要~ Clientが個別に実装すればイイ --SAMLRequestエンドポイント~ --IdPのログアウト用URL **SAMLのテスト [#z844dd42] ***IdP側のテスト [#if943243] テスト用SPを使用してテストすると良い。 -SimpleSAMLphp -SAML 2.0 Test Service Provider ***SP側のテスト [#xafca468] 著名、IdPを使用してテストすると良い。 ***参考 [#e6eb1389] -Qiita --単純なSP側のテスト ---Box と Azure AD を統合して、 Box にシングル サインオン (SSO) する環境を一から構成する~ https://qiita.com/Shinya-Yamaguchi/items/58524d1b62f218514423 --Hybrid-IdPのイントラ側のテスト ---マネージド ドメイン用(AD FS なし) Hybrid Azure AD Join を一から構成する~ https://qiita.com/Shinya-Yamaguchi/items/73016fcdb5beeaefa5ba -naohiro.fujie --IdM実験室 ---[Azure/SAML]Azure Webアプリにお手軽テスト用SAML SPをデプロイする~ https://idmlab.eidentity.jp/2015/04/azuresamlazure-websaml-sp.html ---[SAML]IdPの動作テストに使えるテストSPサイト~ https://idmlab.eidentity.jp/2018/02/samlidpsp.html --SlideShare ---Azure ADと外部アプリのID連携/SSO - Deep Dive~ https://www.slideshare.net/naohiro.fujie/azure-adidsso-deep-dive *例 [#d22e55c7] **シーケンス(Artifact無し) [#jd2a8b15] Technical Overviewから取り出したサンプル・シーケンス ***リクエスト [#k6798a26] -HTTP Redirect Bindingの場合 --302 HTTP/1.1 302 Object Moved Date: 21 Jan 2004 07:00:49 GMT Location:https://idp.example.org/SAML2/SSO/Redirect?SAMLRequest=request&RelayState=... Content-Type: text/html; charset=iso-8859-1 --GET GET /SAML2/SSO/Redirect?SAMLRequest=request&RelayState=... HTTP/1.1 Host: idp.example.org -SAMLRequest=request <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="identifier_1" Version="2.0" IssueInstant="2004-12-05T09:21:59Z" AssertionConsumerServiceIndex="1"> <saml:Issuer> https://sp.example.com/SAML2 </saml:Issuer> <samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/> </samlp:AuthnRequest> -RelayState=value~ SAMLでは、 --[[OAuth]] / [[OpenID Connect]]と違って、Resource Serverをサポートしない。 --故に、SP上のリソースを取得するので、そのリソース入手先のuriを指定する。 ***レスポンス [#q5b1d1c4] -HTTP POST Bindingの場合 --自動POST FORMのレスポンス <form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...> <input type="hidden" name="SAMLResponse" value="response" /> <input type="hidden" name="RelayState" value="value" /> ... <input type="submit" value="Submit" /> </form> --上記のFORMを自動POST POST /SAML2/SSO/POST HTTP/1.1 Host: sp.example.com Content-Type: application/x-www-form-urlencoded Content-Length: nnnn SAMLResponse=response&RelayState=value -SAMLResponse=response~ [[下記アサーション>#hd8b18d8]]を参照 -RelayState=value~ [[上記リクエスト>#k6798a26]]と同じ値を返す。 ***アサーション [#hd8b18d8] <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有り) [#i6ecd2e5] 医療分野共通認証基盤整備コンソーシアムのドキュメントから取り出したサンプル・シーケンス ***リクエスト1 [#i6d11cd4] -HTTP Redirect Bindingの場合 --302 HTTP/1.1 302 Object Moved Date: 21 Jan 2004 07:00:49 GMT Location:https://auth.pki.med.or.jp/sso/SSORedirect/metaAlias/idp?SAMLRequest=... Content-Type: text/html; charset=iso-8859-1 --GET GET /sso/SSORedirect/metaAlias/idp?SAMLRequest=... HTTP/1.1 Host: auth.pki.med.or.jp -HTTP POST Bindingの場合 --POST FORMのレスポンス <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN“ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <body onload="document.forms[0].submit()"> <noscript> <p> <strong>Note:</strong> Since your browser does not support JavaScript、you must press the Continue button once to proceed. </p> </noscript> <form action=https://ServiceProvider.com/SAML/SLO/Browser method="post"> <div> <input type="hidden" name="RelayState“ value="0043bfc1bc45110dae17004005b13a2b"/> <input type="hidden" name="SAMLRequest“ value="PHNhbWxwOkxvZ291dFJlcXVlc3QgeG1sbnM6c2FtbHA9InVybjpvYX NpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgG1sbnM9InVybjpvYXN pczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iDQogICAgSUQ9ImQyYjdj Mzg4Y2VjMzZmYTdjMzljMjhmZDI5ODY0NGE4IiBJc3N1ZUluc3RhbnQ9IjIwM DQtMDEtMjFUMTk6MDA6NDlaIiBWZXJzaW9uPSIyLjAiPg0KICAgIDxJc3N1 ZXI+aHR0cHM6Ly9JZGVudGl0eVByb3ZpZGVyLmNvbS9TQU1MPC9Jc3N1ZXI +DQogICAgPE5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1 MOjIuMDpuYW1laWQtZm9ybWF0OnBlcnNpc3RlbnQiPjAwNWEwNmUwLWF kODItMTEwZC1hNTU2LTAwNDAwNWIxM2EyYjwvTmFtZUlEPg0KICAgIDxz YW1scDpTZXNzaW9uSW5kZXg+MTwvc2FtbHA6U2Vzc2lvbkluZGV4Pg0KPC9 zYW1scDpMb2dvdXRSZXF1ZXN0Pg=="/> </div> <noscript> <div> <input type="submit" value="Continue"/> </div> </noscript> </form> </body> </html> --上記のFORMをPOST POST /sso/SSOPost/... HTTP/1.1 Host: auth.pki.med.or.jp Content-Type: application/x-www-form-urlencoded Content-Length: nnnn SAMLRequest=request&RelayState=value -SAMLRequest <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="s2cee63177ff33bcacd5263caa4af9da101837de24" Version="2.0" IssueInstant="2011-06-28T05:08:41Z" Destination="https://auth.pki.med.or.jp/sso/SSORedirect/metaAlias/idp" ForceAuthn="false" IsPassive="false" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" AssertionConsumerServiceURL="https://ServiceProvider.com/SAML/Consumer/metaAlias/sp"> <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> sso-sp </saml:Issuer> <samlp:NameIDPolicy xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" SPNameQualifier="openam-sp" AllowCreate="true"> </samlp:NameIDPolicy> <samlp:RequestedAuthnContext xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Comparison="exact"> <saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> urn:oasis:names:tc:SAML:2.0:ac:classes:X509 </saml:AuthnContextClassRef> </samlp:RequestedAuthnContext> </samlp:AuthnRequest> ***レスポンス1 [#r81ef2fa] -HTTP Redirect Bindingの場合 --302 HTTP/1.1 302 Object Moved Date: 21 Jan 2004 07:00:49 GMT Location:https://ServiceProvider.com/SAML/SLO/Browser?SAMLart=...&RelayState=... Content-Type: text/html; charset=iso-8859-1 --GET GET /SAML/SLO/Browser?SAMLart=...&RelayState=... HTTP/1.1 Host: ServiceProvider.com -HTTP POST Bindingの場合 --仕様中に、formも使用可能とある(≒ HTTP POST Binding使用可能)。 --が、記載無し ... SAMLart送付にPOST不要と言う判断なのだろう。 ***リクエスト2 [#q0f87612] 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 [#bdb0fdd3] 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> ***アサーション [#a04db016] <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) [#b66ae71f] ***リクエスト [#aaddb118] <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> ***レスポンス [#iece233f] <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> ***アサーション [#g2460853] <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) [#ec8253fd] ***リクエスト [#u30e5212] <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> ***レスポンス [#p669f087] <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> ***アサーション [#m9c5ad0a] <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> *参考 [#q968ebd8] -SAML認証に関する自分なりのまとめ - なんとな~くしあわせ?の日記~ https://nantonaku-shiawase.hatenablog.com/entry/2016/07/13/081053 -SAML2.0でのシングルサインオン実装と戦うあなたに(.NET編) - Qiita~ https://qiita.com/ea54595/items/e932644477a45070690b -SAML Token - samltool.io~ https://samltool.io/ **OneLogin [#m5a97de5] ***developers.onelogin.com [#p5927708] -C# & ASP.NET SAML Authentication Examples~ C Sharp ASP SAML Single Sign-On (SSO) Tutorial~ https://developers.onelogin.com/saml/c-and-aspnet -onelogin/dotnet-saml: SAML toolkit for .NET~ https://github.com/onelogin/dotnet-saml ***SAMLTool.com [#ne63aadb] -SAML Testing Tools | Online SAML Debugger | Examples~ https://www.samltool.com/index.php -ONLINE TOOLS~ https://www.samltool.com/online_tools.php --X.509 CERTS~ https://www.samltool.com/sign_authn.php ---Obtain Self-Signed Certs~ https://www.samltool.com/self_signed_certs.php ---Calculate Fingerprint~ https://www.samltool.com/fingerprint.php ---Format X.509 Certificate~ https://www.samltool.com/format_x509cert.php ---Format Private Key~ https://www.samltool.com/format_privatekey.php --CODE / DECODE~ ---Base64~ https://www.samltool.com/base64.php ---Gzip~ https://www.samltool.com/gzip.php ---URL Encode/Decode~ https://www.samltool.com/url.php ---Deflate + Base64 Encode~ https://www.samltool.com/encode.php ---Base 64 Decode + Inflate~ https://www.samltool.com/decode.php --ENCRYPT / DECRYPT ---Encrypt XML~ https://www.samltool.com/encrypt.php ---Decrypt XML~ https://www.samltool.com/decrypt.php --SIGN~ ---AuthNRequest~ https://www.samltool.com/sign_authn.php ---Response~ https://www.samltool.com/sign_response.php ---Logout Request~ https://www.samltool.com/sign_logout_req.php ---Logout Response~ https://www.samltool.com/sign_logout_res.php ---Metadata~ https://www.samltool.com/sign_metadata.php --VALIDATE~ ---XML Against XSD Schema~ https://www.samltool.com/validate_xml.php ---SAML AuthN Request~ https://www.samltool.com/validate_authn_req.php ---SAML Response~ https://www.samltool.com/validate_response.php ---SAML Logout Request~ https://www.samltool.com/validate_logout_req.php ---SAML Logout Response~ https://www.samltool.com/validate_logout_res.php --ATTRIBUTE EXTRACTOR~ --XML PRETTY PRINT~ --BUILD METADATA~ --EXAMPLES~ --EXTERNAL SAML TOOLS~ **Sustainsys/Saml2 [#ve79906f] ***GitHub [#s45032b5] -SignedXml fails to validate second signature in same document · Issue #32526 · dotnet/corefx~ https://github.com/dotnet/corefx/issues/32526 --https://github.com/AndersAbel/DualXmlDsigBug -Sustainsys/Saml2: Saml2 Authentication services for ASP.NET~ https://github.com/Sustainsys/Saml2 >https://github.com/Sustainsys/Saml2/blob/master/Sustainsys.Saml2/XmlHelpers.cs#L368 ***NuGet [#c6d9b1a1] -NuGet Gallery | Sustainsys.Saml~ https://www.nuget.org/packages/Sustainsys.Saml2/ **SignedXmlの署名・検証の問題対策 [#i172c117] -[[SignedXml>XML#f588cc7d]] -https://gist.github.com/daisukenishino2/69074e571cf89c23cce6d1522abc67e5 --ネストしたXMLの署名・検証処理の問題の確認用コード。 --使用する範囲(SAML2 Assertionの署名・検証)で、問題なく動作するものと思われる。 **IdM実験室 [#k52e511d] -Azure ADのSAML対応(IdP編)~ https://idmlab.eidentity.jp/2014/08/azure-adsamlidp.html -IdM実験室: 続Azure ADのSAML対応(IdP編)~SP Initiatedに対応~ https://idmlab.eidentity.jp/2014/09/azure-adsamlidpsp-initiated.html -[Office365/AzureAD]OpenAMとのID連携 --①~ https://idmlab.eidentity.jp/2014/11/office365azureadopenamid.html --②~ https://idmlab.eidentity.jp/2014/12/office365azureadopenamid.html --③~ https://idmlab.eidentity.jp/2014/12/office365azureadopenamid_25.html -[AzureAD/Java]WebLogic/JavaアプリケーションとAzure ADを連携する~ https://idmlab.eidentity.jp/2016/01/azureadjavaweblogicjavaazure-ad.html -[AD FS] --[AD FS]プライバシーに考慮したID連携設定~ https://idmlab.eidentity.jp/2014/12/ad-fsid.html --JavaアプリSPとSAML Artifact Bindingで連携する際の証明書ストア~ https://idmlab.eidentity.jp/2016/01/ad-fsjavaspsaml-artifact-binding.html ---- Tags: [[:IT国際標準]], [[:認証基盤]], [[:クレームベース認証]], [[:SAML]]