Java >> Java チュートリアル >  >> Tag >> assert

SAML プロトコルでの SAML アサーションでのクロックスキューの使用

この投稿では、SAML アサーションでクロックスキューを使用して、サービス プロバイダー (SP) が ID プロバイダー (IdP) から SAML 応答を受信する際の一般的な問題を回避する方法について説明します。が一般的なシナリオです。

したがって、ユーザーが SP アプリケーションにアクセスすると、SP は認証要求を IdP に送信し、IdP は SAML 応答を SP に送信します。典型的な SAML 応答は以下のようになります:

<saml2p:Response Destination="https://localhost:8443/spring-security-saml2-sample/saml/SSO"
                 ID="_8ced26c57648ea420c5e27ac7f3d78b3"
                 InResponseTo="a3ei0bej41ie0dg738jji60271f1bca"
                 IssueInstant="2018-10-31T18:39:05.109Z"
                 Version="2.0"
                 xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 >
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://sts.betterjavacode.com/sts</saml2:Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
            <ds:Reference URI="#_8ced26c57648ea420c5e27ac7f3d78b3">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                        <ec:InclusiveNamespaces PrefixList="xsd"
                                                xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
                                                />
                    </ds:Transform>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                <ds:DigestValue>k6k9seVwZT8qEfainB+HDUJmv7wLwPjJxRARgrFLk3E=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>
eYl7/5Bg4f2ZtXYl1Tp/ZW4CIqna1sjHjVSB/zhj3NHncQu7pq9PBTdWz0JEaE8+efICz7trDQvI
J0tih35Vg7NqDtOeps7vMttV0XvrnWKIXEqrscyNgkhwy+KW2oprKIWTJq6y3Z0kQ7n2DlTRkfAE
yLRPxqr8AZU+77Tbv4DmTQVp934ivibUaMNU79nkhMMo7vf0ldpeNCe5Ll5Q7nxgNBCrL4mhbGdU
DNJDVqJIhQZDJUYhBVZSgLo6mYLxf0ndQr5+GdcvO3i8VlooH49I5ZO6LfsBlNiSU6WezC0Fcz8J
biodrT3h62Jny8FKUgYfXA8i0ZoAerCxHmLGFQ==
</ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509Certificate>MIICpTCCAY2gAwIBAgIHAKQk/Tty7TANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhJbmZvclNU
UzAeFw0xNzExMTAxNjIwMjVaFw0xOTExMTAxNjIwMjZaMBMxETAPBgNVBAMMCEluZm9yU1RTMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuy40GofgfSldiu7AXRSWQZo8YIUmdJOXV5gd
YUiIBggcm5J+jttd21av9AWBDLtvekIqgG+nM1SEarDNlCgrnThqDtdsBDnT+B5FQowLwqNQZb0C
6PSWccp484OLHhv3YwbjV/IxgW6wlv2EejPF93NTPc5TkkpIKIEARJwKiUvuwzkcX1atD8HESj8/
5wZhK3g3MSv+CaJb1Y732U2aa34RI6HYRNlKRsqRj55SZnPs3AmIBL/rdVbt5eYJdK+jXSOMQ9Sb
TNkgTAYKnlSQP8NhsNc1Y5ZJ231KD3rSqHEXwpKVXFuEgtBnCL9utqyUU0Fu9PNJJj0hf9otMJw2
pQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAsqxA/+llqNtJq/VPtAa0XwtldB7/4Gew5LgfU5Yj7
/ruHuxCh03xfnLyjo0bxrFeMbhHMg4MzJhgah0zTIl4WMRI781CiMxGfMdvQAHhY5hgpryqKUTbH
qcIoW1WkTEL+TrOSk2gjL/n/4KsUJ3XKeI4j4h2RDvbIF8u9cbrB5RupEwJlo/pK3mCr3GQGFxVX
4yli+AysMmz8JWz2hWQad0QQr9KIYmZdgauNt7uYn4u+7cngtTtQF/EMoZU1pAFI5lDP13mxI1rR
eYGzoKhGfHIy7TiXYvqX0vFomzkgr6D0DnRlRkQR8J5EVtnGZ7sF50KlNviG+IxrPNndUdeX</ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </ds:Signature>
    <saml2p:Status>
        <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
    </saml2p:Status>
    <saml2:Assertion ID="_43514fee402111bfa8ef07e2bb3e1816"
                     IssueInstant="2018-10-31T18:39:05.109Z"
                     Version="2.0"
                     xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
                     >
        <saml2:Issuer>https://sts.betterjavacode.com/sts</saml2:Issuer>
        <saml2:Subject>
            <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
                          NameQualifier="https://sts.betterjavacode.com/sts"
                          SPNameQualifier="https://localhost:8443/spring-security-saml2-sample/saml/metadata"
                          >-74375301938178262591541011144180</saml2:NameID>
            <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <saml2:SubjectConfirmationData InResponseTo="a3ei0bej41ie0dg738jji60271f1bca"
                                               NotOnOrAfter="2018-10-31T18:44:05.109Z"
                                               Recipient="https://localhost:8443/spring-security-saml2-sample/saml/SSO"
                                               />
            </saml2:SubjectConfirmation>
        </saml2:Subject>
        <saml2:Conditions NotBefore="2018-10-31T18:39:05.109Z"
                          NotOnOrAfter="2018-10-31T18:44:04.109Z"
                          >
            <saml2:AudienceRestriction>
                <saml2:Audience>https://localhost:8443/spring-security-saml2-sample/saml/metadata</saml2:Audience>
            </saml2:AudienceRestriction>
        </saml2:Conditions>
        <saml2:AttributeStatement>
            <saml2:Attribute Name="http://schemas.microsoft.com/claims/Tenant">
                <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                      xsi:type="xsd:string"
                                      >ABC Company</saml2:AttributeValue>
            </saml2:Attribute>
            <saml2:Attribute Name="http://schemas.microsoft.com/claims/Identity">
                <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                      xsi:type="xsd:string"
                                      >testuser</saml2:AttributeValue>
            </saml2:Attribute>
            <saml2:Attribute Name="http://schemas.xmlsoap.org/claims/CommonName">
                <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                      xsi:type="xsd:string"
                                      >Test User</saml2:AttributeValue>
            </saml2:Attribute>

            <saml2:Attribute Name="http://schemas.microsoft.com/claims/Email">
                <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                      xsi:type="xsd:string"
                                      >[email protected]</saml2:AttributeValue>
            </saml2:Attribute>
            <saml2:Attribute Name="http://schemas.microsoft.com/claims/Session">
                <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                      xsi:type="xsd:string"
                                      >-65311121040491585821541011144177</saml2:AttributeValue>
            </saml2:Attribute>                        
        </saml2:AttributeStatement>
        <saml2:AuthnStatement AuthnInstant="2018-10-31T18:39:05.109Z"
                              SessionIndex="31079178551135950171541011144177"
                              >
            <saml2:AuthnContext>
                <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml2:AuthnContextClassRef>
            </saml2:AuthnContext>
        </saml2:AuthnStatement>
    </saml2:Assertion>
</saml2p:Response>

現在、SP と IdP は別のマシン上にあります。また、クロックが同期されていない場合もあります。したがって、IdP が応答を生成するとき、要素 SubjectConfirmationData があります。 NotBefore を含む そして NotOnOrAfter. Subject アサーションを受信して​​いるユーザーと証明書利用者に関する詳細を示します。依拠当事者は、アサーションが正しい発行者からのものであることを確認する必要があります。

NotBefore – サブジェクトが検証されなくなるまでの時間。

NotOnOrAfter – 被験者の有効期限が切れた後。

同様に、Conditions があります。 アサーションの要素であり、この要素には属性 NotBefore も含まれます または NotOnOrAfter .これら 2 つの属性は、アサーションが有効になる時刻と、有効期限が切れる時刻を示します。

問題

ここで、IdP と SP のシステム クロックが同期していないシナリオを考慮し、Idp クロックが Sp クロックよりも進んでいる場合、このシナリオをどのように処理しますか?

解決策

上記のシナリオで説明したように、NotBefore が原因でアサーションの検証が失敗します。 時間は SP マシンの時間より長くなります。

この問題を解決するには、IdP と SP のクロックが同期していることを確認します。しかし、これは人間に依存する解決策のようであり、クロックを同期させることは必ずしも実用的な解決策ではありません.

これを解決する別の方法として、SAML アサーションにクロックスキューを追加する方法があります。アサーションを使用している依拠当事者は、小さなクロックスキューを時間に適用して、時間の小さな変化に対応する必要があります。

private int clockSkew = 120;

SubconfirmationData subjectConfirmationData = subjectConfirmation.getSubjectConfirmationData();

if(subjectConfirmationData.getNotOnOrAfter().plusSeconds(clockSkew).isBeforeNow())
{
 // throw error - Subject Confirmation Data has expired
}

/***
*
*
*/

if (conditions.getNotBefore() != null && conditions.getNotBefore().minusSeconds(clockSkew).isAfterNow()) 
{
      throw new SAMLException("Assertion condition notBefore is not valid");
}

if (conditions.getNotOnOrAfter() != null && conditions.getNotOnOrAfter().plusSeconds(clockSkew).isBeforeNow()) 
{
      throw new SAMLException("Assertion condition notOnOrAfter is not valid");
}

参考文献

<オール>
  • SAML 仕様
  • NotBefore と NotOnOrAfter を使用した SAML アサーション

  • No
    Java タグ