Single Sign On using Security Assertion Markup Language
Few options
Identity Provider (IDP) is used for authentication purposes only. It is replacing login screen :)Service Provider (SP, application) will do authorization by reading roles from LDAP/database...
or
IDP will be used for authentication and authorization.
Problem with this approach is that SP does not know when role changes.
Session information can be stored using cookies on SP and IDP domain, so IDP can verify if user user is already logged on another SP.
Flow:
- User comes to SP (User is not logged. SP and IDP does not have any information about user)
- There is no session on SP for this user and user is redirected to IDP
- IDP authenticate user and send SAML response to SP
- SP validates SAML response and reads roles from datasource and the session is established
- User comes to SP2 (another application)
- SP2 does not have a session and asks IDP about this user.
- IDP knows this user has session so user is not provided with login screen. IDP reads data from datasource and returns SAML response to SP2
- SP2 validates SAML response and reads roles from LDAP
- User has seamlessly logged to SP2
IDP notes
IdP only reads, never having any sort of admin access. This helps security wise, knowing that authentication system can't write or retrieve sensitive information.Common problems
Problem
DEBUG (SAMLProcessingFilter.java:99) - Incoming SAML message is invalid
org.opensaml.ws.security.SecurityPolicyException: Validation of protocol message signature failed
Solution
Verify that SP and IDP have proper metadata.Problem
14:54:00.798 [http-nio-8082-exec-6] DEBUG (SAMLProcessingFilter.java:99) - Incoming SAML message is invalid
org.opensaml.ws.security.SecurityPolicyException: Validation of protocol message signature failed
at org.opensaml.common.binding.security.SAMLProtocolMessageXMLSignatureSecurityPolicyRule.doEvaluate(SAMLProtocolMessageXMLSignatureSecurityPolicyRule.java:138)
at org.opensaml.common.binding.security.SAMLProtocolMessageXMLSignatureSecurityPolicyRule.evaluate(SAMLProtocolMessageXMLSignatureSecurityPolicyRule.java:107)
at org.opensaml.ws.security.provider.BasicSecurityPolicy.evaluate(BasicSecurityPolicy.java:51)
at org.opensaml.ws.message.decoder.BaseMessageDecoder.processSecurityPolicy(BaseMessageDecoder.java:132)
at org.opensaml.ws.message.decoder.BaseMessageDecoder.decode(BaseMessageDecoder.java:83)
at org.opensaml.saml2.binding.decoding.BaseSAML2MessageDecoder.decode(BaseSAML2MessageDecoder.java:70)
at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:105)
Solution
Add IDP public key for signing messages to java key store. It can be found in incoming saml message from IDP.http://stackoverflow.com/questions/23059203/http-status-401-authentication-failed-incoming-saml-message-is-invalid-with
Problem
InResponseToField of the Response doesn't correspond to sent messageLog
2016-10-26 12:33:20,159 DEBUG PROTOCOL_MESSAGE,http-nio-8080-exec-4:74 -
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://mercurybi-local:8080/mercurybi/saml/SSO" Destination="https://authstack/saml2.0/sso" ForceAuthn="false" ID="a293907a4b8ed0d21iggb0ci9dc0bbb" IsPassive="false" IssueInstant="2016-10-26T10:33:20.100Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">SAMARA_SP</saml2:Issuer>
</saml2p:AuthnRequest>
2016-10-26 12:33:22,427 DEBUG PROTOCOL_MESSAGE,http-nio-8080-exec-5:113 -
<?xml version="1.0" encoding="UTF-8"?><samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" Destination="http://mercurybi-local:8080/mercurybi/saml/SSO" ID="_4981b4a45c61a289809108b15d7c401bb2c0bcdae5" InResponseTo="a293907a4b8ed0d21iggb0ci9dc0bbb" IssueInstant="2016-10-26T10:33:20Z" Version="2.0">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://authstack</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
2016-10-26 12:33:22,698 DEBUG HttpSessionStorage,http-nio-8080-exec-5:117 - Message a293907a4b8ed0d21iggb0ci9dc0bbb not found in session A9C98F53D692EDFA486D96FB3D9F67C6
2016-10-26 12:33:22,702 DEBUG SAMLAuthenticationProvider,http-nio-8080-exec-5:98 - Error validating SAML message
org.opensaml.common.SAMLException: InResponseToField of the Response doesn't correspond to sent message a293907a4b8ed0d21iggb0ci9dc0bbb
Solution
<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl"> <property name="storageFactory"> <bean class="org.springframework.security.saml.storage.EmptyStorageFactory"/> </property> </bean>
Problem and Solution
Application is hosted on 2 different machines using different domains.IDP manages to return proper domain name based on following rules
- read where to return in SP metadata
- if AssertionConsumerServiceURL field is present in SAML request use that one
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest
AssertionConsumerServiceURL="http://app.samara.hr:8080/app/saml/SSO"
Destination="https://myIDP/saml2.0/sso" ForceAuthn="false"
ID="a4bi2g9cj906hj4429i0b0413h5aji4" IsPassive="false"
IssueInstant="2016-11-03T13:57:40.212Z"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol">
<saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">SAMARA-SP</saml2:Issuer>
</saml2p:AuthnRequest>
Logout and SingleLogout feature
What will be URL used for redirects (if that option is used) update SP metadata:
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://mydomain.samara.hr/myApp/saml/SingleLogout"/>
Send SAML request via POST
To be sure POST is used:
@Bean
public WebSSOProfileOptions defaultWebSSOProfileOptions() {
final WebSSOProfileOptions webSSOProfileOptions = new WebSSOProfileOptions();
webSSOProfileOptions.setIncludeScoping(false);
webSSOProfileOptions.setBinding(SAMLConstants.SAML2_POST_BINDING_URI);
return webSSOProfileOptions;
}
Ref:
SWITCH - Demookta - SAML
SAML Security Cheat Sheet
Spring Security SAML
Spring SAML - Troubleshooting common problems
Can one SP metadata file be used for 5 separate SPs running the same application