マイクロソフト系技術情報 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を使っていたが
最近は通信速度や端末性能の向上により、使われることは減ってきているらしい。

SPとIdPの間で直接通信をさせなければならないので、
クラウドサービスと社内IdPを連携させる場合など面倒なため。

ただ、今でも稀にArtifact Bindingしか使えないSPが
存在するので、仕方なく(IdP側に)実装することがある。

なお、AD FSではArtifact Bindingをサポートしている。
Azure ADはPOST BindingのみでArtifact Bindingは使えない。

詳細

プロトコル&アサーション

AuthnRequest?

Assertion

を参考にする。

Response

を参考にする。

エンコード・デコード

下記のsamltool.ioからアサーションを取得し、SAMLTool.comで確認するなど。

HTTP Redirect Binding

HTTP POST Binding

署名・検証のポイント

ネストした複数のXML署名が Verify できない

SignedXml?クラスの実装に問題があり、
ネストした複数のXML署名が Verify できないという問題があるらしい。

※ 外側だけ検証すればイイ気がする。
 コチラが、SignedXml?によるネストしたXML署名・検証結果。

Whitespace を保持したままのXML署名が Verify できない

XmlDocuement? を利用する際に PreserveWhitespace? を単に true にする。

SAML v2 schema(XSD) による SAML(XML) の検証

以下を用いて、SAMLを検証する。

しかし、結局XPathで検証していたりする。
(適切な、ミニマムのXSDをオンラインで発見できないため)

SAMLTool.com(エンコード・デコード、署名・検証)

登録情報

IdP/STS側

Client側

SAMLのテスト

IdP側のテスト

SP側のテスト

著名、IdPを使用してテストする。

参考

シーケンス(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>

参考

OneLogin?

developers.onelogin.com

SAMLTool.com

Sustainsys/Saml2

GitHub

NuGet

SignedXml?の署名・検証の問題対策

IdM実験室


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


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS