「[[マイクロソフト系技術情報 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(Public UserID)
 ○ emailAddress
 ○ persistent(永続的仮名 - Pairwise UserID)
 ☓ 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]
[[SAML Assertions>SAML Assertions#a6ae2b31]]に指定する。

***unspecified [#ef6434a7]
既定値(ユーザ名)

***entity [#s3c734a2]
UserId(Public UserID)

***emailAddress [#x22f87c7]
メアド

***persistent [#t65eabb9]
UserId(Pairwise UserID)

**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]
-Shinya Yamaguchi(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/

**[[XML署名・暗号]] [#s54e7149]

**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

**[[XML署名・暗号]] [#s54e7149]

**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]] には [[問題>#k3724cb3]] がある。

-https://gist.github.com/daisukenishino2/69074e571cf89c23cce6d1522abc67e5
--ネストしたXMLの署名・検証処理の問題の確認用コード。
--使用する範囲(SAML2 Assertionの署名・検証)で、問題なく動作するものと思われる。

-OpenTouryo/SignedXml2.cs at develop · OpenTouryoProject/OpenTouryo~
https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Frameworks/Infrastructure/Public/Security/Xml/SignedXml2.cs
--上記のgist.github.comの内容でライブラリ化した。
--[[汎用認証サイト>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]]のSAML対応で使ってます(動いてるっちゃ動いてる)。

----
Tags: [[:IT国際標準]], [[:認証基盤]], [[:クレームベース認証]], [[:SAML]]

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS