Spring SAML Security with PingIdentity / PingFederation

Spring SAML application for security security does not work for me when I integrate it with PingIdentity. After receiving the redirect to idp, loggin to Ping ok, having received a good saml statement, redirect back to the SAML security application in Spring, I get an infinite loop with an access denied error in the spring-security stack. And the org.sourceid error in Ping. Error in the Ping log (right before making a good SAML statement):

org.sourceid.saml20.profiles.StatusResponseException: Unknown AssertionConsumerServiceURL https://xxxwm07.integration.company.at:9031/sp/ACS.saml2

Access Denial Error in Spring:

2017-09-18 09:48:00 INFO stdout:71 – 2017-09-18 09:48:00 DEBUG HttpSessionStorage:93 – Storing message a2iiedhi69h081391e3biag591i7a2f to session FVAX79n-fxixNnIApUrrLe2V 2017-09-18 09:48:00 DEBUG HttpSessionStorage:93 – Storing message a2iiedhi69h081391e3biag591i7a2f to session FVAX79n-fxixNnIApUrrLe2V 2017-09-18 09:48:00 INFO stdout:71 – 2017-09-18 09:48:00 INFO SAMLDefaultLogger:127 – AuthNRequest;SUCCESS;10.69.208.181;app1;pingidentity;;; 2017-09-18 09:48:00 INFO SAMLDefaultLogger:127 – AuthNRequest;SUCCESS;10.69.208.18;app1;pingidentity;;; 2017-09-18 09:48:00 INFO stdout:71 – 2017-09-18 09:48:00 DEBUG SecurityContextPersistenceFilter:97 – SecurityContextHolder now cleared, as request processing completed 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/favicon.ico’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/images/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/css/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/logout.jsp’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/saml/web/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterChainProxy:337 – /index.jsp at position 1 of 8 in additional filter chain; firing Filter: ‘SecurityContextPersistenceFilter’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG HttpSessionSecurityContextRepository:139 – HttpSession returned null object for SPRING_SECURITY_CONTEXT 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG HttpSessionSecurityContextRepository:85 – No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@2f3ea906. A new one will be created. 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterChainProxy:337 – /index.jsp at position 2 of 8 in additional filter chain; firing Filter: ‘FilterChainProxy’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/saml/login/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/saml/logout/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/saml/metadata/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/saml/sso/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/saml/ssohok/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/saml/singlelogout/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AntPathRequestMatcher:103 – Checking match of request : ‘/index.jsp’; against ‘/saml/discovery/**’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterChainProxy:180 – /index.jsp has no matching filters 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterChainProxy:337 – /index.jsp at position 3 of 8 in additional filter chain; firing Filter: ‘RequestCacheAwareFilter’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG DefaultSavedRequest:309 – pathInfo: both null (property equals) 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG DefaultSavedRequest:309 – queryString: both null (property equals) 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG DefaultSavedRequest:325 – requestURI: arg1=/app1/; arg2=/app1/ (property equals) 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG DefaultSavedRequest:325 – serverPort: arg1=8443; arg2=8443 (property equals) 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG DefaultSavedRequest:325 – requestURL: arg1=https://xxxwm07.integration.company.at:8443/app1/; arg2=https://xxxwm07.integration.company.at:8443/app1/ (property equals) 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG DefaultSavedRequest:325 – scheme: arg1=https; arg2=https (property equals) 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG DefaultSavedRequest:325 – serverName: arg1=xxxwm07.integration.company.at; arg2=xxxwm07.integration.company.at (property equals) 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG DefaultSavedRequest:325 – contextPath: arg1=/app1; arg2=/app1 (property equals) 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG DefaultSavedRequest:325 – servletPath: arg1=/index.jsp; arg2=/index.jsp (property equals) 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG HttpSessionRequestCache:62 – Removing DefaultSavedRequest from session if present 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterChainProxy:337 – /index.jsp at position 4 of 8 in additional filter chain; firing Filter: ‘SecurityContextHolderAwareRequestFilter’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterChainProxy:337 – /index.jsp at position 5 of 8 in additional filter chain; firing Filter: ‘AnonymousAuthenticationFilter’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AnonymousAuthenticationFilter:102 – Populated SecurityContextHolder with anonymous token: ‘org.springframework.security.authentication.AnonymousAuthenticationToken@905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 10.69.208.181; SessionId: FVAX79n-fxixNnIApUrrLe2V; Granted Authorities: ROLE_ANONYMOUS’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterChainProxy:337 – /index.jsp at position 6 of 8 in additional filter chain; firing Filter: ‘SessionManagementFilter’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterChainProxy:337 – /index.jsp at position 7 of 8 in additional filter chain; firing Filter: ‘ExceptionTranslationFilter’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterChainProxy:337 – /index.jsp at position 8 of 8 in additional filter chain; firing Filter: ‘FilterSecurityInterceptor’ 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterSecurityInterceptor:194 – Secure object: FilterInvocation: URL: /index.jsp; Attributes: [IS_AUTHENTICATED_FULLY] 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG FilterSecurityInterceptor:310 – Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 10.69.208.18; SessionId: FVAX79n-fxixNnIApUrrLe2V; Granted Authorities: ROLE_ANONYMOUS 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AffirmativeBased:65 – Voter: org.springframework.security.access.vote.RoleVoter@18d957ee, returned: 0 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG AffirmativeBased:65 – Voter: org.springframework.security.access.vote.AuthenticatedVoter@651bd700, returned: -1 2017-09-18 09:48:01 INFO stdout:71 – 2017-09-18 09:48:01 DEBUG ExceptionTranslationFilter:165 – Access is denied (user is anonymous); redirecting to authentication entry point 2017-09-18 09:48:01 INFO stdout:71 – org.springframework.security.access.AccessDeniedException: Access is denied 2017-09-18 09:48:01 INFO stdout:71 – at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) I'm going to get back to debugging Spring Security, but if you have any tips, this will be awesome. as you can see in this Spring sec log, everything looks fine with ping, the role selector is fine, then the authenticated user selector fails. and why do I end up as an anonymous user after a good ping authentication? It seems some kind of user principle should be matched with ping on spring, yes?

If only a hint on where to start in my Spring Security debugging would be very helpful ...

Thanks in advance

Both versions of IdP and SP in the Spring SAML Sample application are file based. Here are the details:

******* securityConext.xml

<bean id="metadata"
    class="org.springframework.security.saml.metadata.CachingMetadataManager">
    <constructor-arg>
        <list>
            <!-- IDP Metadata configuration -->
            <bean
                class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
                <constructor-arg>
                    <bean
                        class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider">
                        <constructor-arg>
                            <bean class="java.util.Timer" />
                        </constructor-arg>
                        <constructor-arg>
                            <bean class="org.opensaml.util.resource.ClasspathResource">
                                <constructor-arg value="/metadata/idp.xml" />
                            </bean>
                        </constructor-arg>
                        <property name="parserPool" ref="parserPool" />
                    </bean>
                </constructor-arg>
                <constructor-arg>
                    <bean
                        class="org.springframework.security.saml.metadata.ExtendedMetadata" />
                </constructor-arg>
                <property name="metadataTrustCheck" value="false" />

            </bean>

            <!-- SP Metadata configuration -->
            <bean
                class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
                <constructor-arg>
                    <bean
                        class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider">
                        <constructor-arg>
                            <bean class="java.util.Timer" />
                        </constructor-arg>
                        <constructor-arg>
                            <bean class="org.opensaml.util.resource.ClasspathResource">
                                <constructor-arg value="/metadata/sp.xml" />
                            </bean>
                        </constructor-arg>
                        <property name="parserPool" ref="parserPool" />
                    </bean>
                </constructor-arg>
                <constructor-arg>
                    <bean
                        class="org.springframework.security.saml.metadata.ExtendedMetadata">
                        <property name="local" value="true" />
                        <property name="securityProfile" value="pkix" />
                        <property name="sslSecurityProfile" value="pkix" />
                        <property name="sslHostnameVerification" value="default" />
                        <property name="signMetadata" value="false" />
                        <property name="signingKey" value="ping" />
                        <property name="encryptionKey" value="mykey" />
                        <property name="tlsKey" value="ping" />
                        <property name="requireArtifactResolveSigned" value="false" />
                        <property name="requireLogoutRequestSigned" value="false" />
                        <property name="requireLogoutResponseSigned" value="false" />
                        <property name="idpDiscoveryEnabled" value="false" />
                        <property name="idpDiscoveryURL" value="http://www.google.com" />
                        <property name="idpDiscoveryResponseURL" value="http://www.google.com" />
                    </bean>
                </constructor-arg>
            </bean>

        </list>
    </constructor-arg>
    <!-- OPTIONAL used when one of the metadata files contains information 
        about this service provider -->
    <!-- <property name="hostedSPName" value=""/> -->
    <!-- OPTIONAL property: can tell the system which IDP should be used for 
        authenticating user by default. -->
    <!-- <property name="defaultIDP" value="http://localhost:8080/opensso"/> -->
</bean>

***** idp.xml

<md:EntityDescriptor ID="jWQF6vBDwO-0.YYnI3YL91qXp-O"
cacheDuration="PT1440M" entityID="pingidentity" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"
    WantAuthnRequestsSigned="false">
    <md:KeyDescriptor use="signing">
        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:X509Data>
                <ds:X509Certificate>MIIDQD...q9kMuY=
                </ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:KeyDescriptor use="encryption">
        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:X509Data>
                <ds:X509Certificate>MIID...q9kMuY=
                </ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:ArtifactResolutionService index="0"
        Location="https://xxxwm07.integration.company.at:9031/idp/ARS.ssaml2"
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" isDefault="true" />
    <md:SingleLogoutService
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
        Location="https://xxxwm07.integration.company.at:9031/idp/SLO.saml2" />
    <md:SingleLogoutService
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://xxxwm07.integration.company.at:9031/idp/SLO.saml2" />
    <md:SingleLogoutService
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
        Location="https://xxxwm07.integration.company.at:9031/idp/SLO.saml2" />
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
        Location="https://xxxwm07.integration.company.at:9031/idp/SLO.ssaml2" />
    <md:SingleSignOnService
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://xxxwm07.integration.company.at:9031/idp/SSO.saml2" />
    <md:SingleSignOnService
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
        Location="https://xxxwm07.integration.company.at:9031/idp/SSO.saml2" />
    <md:SingleSignOnService
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
        Location="https://xxxwm07.integration.company.at:9031/idp/SSO.saml2" />
    <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
        Location="https://xxxwm07.integration.company.at:9031/idp/SSO.saml2" />
    <saml:Attribute Name="subject"
        NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
        xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" />
</md:IDPSSODescriptor>
<md:AttributeAuthorityDescriptor
    protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <md:AttributeService
        Location="https://xxxwm07.integration.company.at:9031/idp/attrsvc.ssaml2"
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" />
</md:AttributeAuthorityDescriptor>
<md:ContactPerson contactType="administrative" />

**** sp.xml

<md:EntityDescriptor ID="U.NC.JbPpTmbfH8OQy8l9EhyRBl"
cacheDuration="PT1440M" entityID="app1" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <md:KeyDescriptor use="signing">
        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:X509Data>
                <ds:X509Certificate>MIID....kMuY=
                </ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:KeyDescriptor use="encryption">
        <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:X509Data>
                <ds:X509Certificate>MIID....uY=
                </ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:ArtifactResolutionService index="0"
        Location="https://xxxwm07.integration.company.at:9031/sp/ARS.ssaml2"
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" isDefault="true" />
    <md:SingleLogoutService
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
        Location="https://xxxwm07.integration.company.at:9031/sp/SLO.saml2" />
    <md:SingleLogoutService
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://xxxwm07.integration.company.at:9031/sp/SLO.saml2" />
    <md:SingleLogoutService
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
        Location="https://xxxwm07.integration.company.at:9031/sp/SLO.saml2" />
    <md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
        Location="https://xxxwm07.integration.company.at:9031/sp/SLO.ssaml2" />
    <md:AssertionConsumerService index="0"
        Location="https://xxxwm07.integration.company.at:9031/sp/ACS.saml2"
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" isDefault="true" />
    <md:AssertionConsumerService index="1"
        Location="https://xxxwm07.integration.company.at:9031/sp/ACS.saml2"
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" />
    <md:AssertionConsumerService index="2"
        Location="https://xxxwm07.integration.company.at:9031/sp/ACS.saml2"
        Binding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" />
    <md:AttributeConsumingService index="0">
        <md:ServiceName xml:lang="en">AttributeContract
        </md:ServiceName>
        <md:RequestedAttribute Name="subject" />
    </md:AttributeConsumingService>
</md:SPSSODescriptor>
<md:ContactPerson contactType="administrative" />

*** here is the sp.xml solution generated from the sample application

    <?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
    ID="app1" entityID="app1">
    <md:SPSSODescriptor AuthnRequestsSigned="true"
        WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <md:KeyDescriptor use="signing">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>MIIDQDCCAiigAwIBAg...wq9kMuY=
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </md:KeyDescriptor>
        <md:KeyDescriptor use="encryption">
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <ds:X509Data>
                    <ds:X509Certificate>MIIDQDCCAiigAwIBAgIGAVzUOBXsMA0GCSqGSIb3DQEBCwUAMGExCzAJBgNVBAYTAkFUMSgwJgYD
                        VQQKEx9ldzd1aXB3bTA3LmludGVncmF0...q9kMuY=
                    </ds:X509Certificate>
                </ds:X509Data>
            </ds:KeyInfo>
        </md:KeyDescriptor>
        <md:SingleLogoutService
            Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
            Location="https://host1:8443/app1/saml/SingleLogout" />
        <md:SingleLogoutService
            Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
            Location="https://host1:8443/app1/saml/SingleLogout" />
        <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
        </md:NameIDFormat>
        <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient
        </md:NameIDFormat>
        <md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
        </md:NameIDFormat>
        <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
        </md:NameIDFormat>
        <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
        </md:NameIDFormat>
        <md:AssertionConsumerService
            Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://host1:8443/app1/saml/SSO"
            index="0" isDefault="true" />
    </md:SPSSODescriptor>
</md:EntityDescriptor>
0
1

Spring SAML, Ping Identity. , AssertionConsumerURL, , Spring SAML SAML:

https://xxxwm07.integration.company.at:9031/sp/ACS.saml2
+1

Source: https://habr.com/ru/post/1539656/


All Articles