Java >> Java tutorial >  >> Tag >> assert

Brug af clockskew i SAML Assertion i SAML Protocol

I dette indlæg vil jeg forklare, hvordan vi kan bruge clockskew i SAML Assertion for at undgå et generelt problem, når en Service Provider (SP) modtager et SAML-svar fra Identity Provider (IdP), og hvis begge af dem er på forskellige maskiner, som er generelt scenariet.

Så når en bruger tilgår en SP-applikation, sender SP en godkendelsesanmodning til IdP, og IdP sender et SAML-svar til SP. Det typiske SAML-svar ser ud som nedenfor:

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

Nu er SP og IdP på en anden maskine. Og der kan være en sag om, at deres ure ikke er synkroniseret. Så når IdP genererer svaret, har det et element SubjectConfirmationData der indeholder NotBefore og NotOnOrAfter. Subject angiver detaljer om brugeren og den pålidelige part, der modtager påstanden. Den afhængige part skal verificere, at påstanden kommer fra den rigtige udsteder.

NotBefore – Tidspunkt før hvilket emne ikke kan valideres.

NotOnOrAfter – Tidspunkt for eller efter hvilket emne er udløbet.

På samme måde vil der være Conditions element i påstanden, og dette element vil også indeholde attributter NotBefore eller NotOnOrAfter . Disse to attributter angiver, på hvilket tidspunkt en påstand vil være gyldig, og efter hvilket tidspunkt den vil være udløbet.

Problem

Hvis vi nu tager højde for et scenarie, hvor systemure for IdP og SP ikke er synkroniserede, og hvis Idp-uret er foran Sp-uret, hvordan håndterer vi dette scenarie?

Løsning

Så som beskrevet i ovenstående scenarie, så mislykkes påstandsvalidering på grund af NotBefore tiden vil være længere end tiden på SP-maskinen.

For at løse dette problem kan vi enten sørge for, at IdP- og SP-ure er synkroniserede. Men dette virker til at være menneskeafhængig løsning, og det er ikke altid en praktisk løsning at få ure synkroniseret.

En anden måde kan dette løses ved at tilføje en clockskew i SAML-påstanden. En stolende part, der bruger påstanden, bør anvende en lille urskævhed på tiden for at imødekomme små ændringer i tiden.

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");
}

Referencer

  1. SAML-specifikation
  2. SAML-påstand med NotBefore og NotOnOrAfter

No
Java tag