When I try the SAML logout, I am getting the below error
org.opensaml.saml2.metadata.provider.MetadataProviderException: IDP doesn't contain any SingleLogout endpoints
org.springframework.security.saml.util.SAMLUtil.getLogoutBinding(SAMLUtil.java:104)
org.springframework.security.saml.websso.SingleLogoutProfileImpl.sendLogoutRequest(SingleLogoutProfileImpl.java:74)
org.springframework.security.saml.SAMLLogoutFilter.processLogout(SAMLLogoutFilter.java:138)
org.springframework.security.saml.SAMLLogoutFilter.doFilter(SAMLLogoutFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java
I am using Spring SAML integration
Could any one just tell me the reason for this error. the saml filters are set in the spring xml
<bean id="samlLogoutFilter" class="org.springframework.security.saml.SAMLLogoutFilter">
and
<bean id="samlLogoutProcessingFilter" class="org.springframework.security.saml.SAMLLogoutProcessingFilter">
<constructor-arg ref="successLogoutHandler"/>
<constructor-arg ref="logoutHandler"/>
</bean>
are defined
Looks like the idp you are connecting to isn't supporting single logout. The error message says that the idp's metadata isn't advertising single logout support.
Related
I implemented the Spring SAML sample application using ssocircle and it worked fine. Now I have been trying to implement it for the client's ADFS. Following is the configuration I think that is required, please correct me if I am wrong:
Change the first parameter below, to the federationMetadata.xml url provided by client
<bean class="org.opensaml.saml2.metadata.provider.HTTPMetadataProvider">
<constructor-arg>
<value type="java.lang.String">http://idp.ssocircle.com/idp-meta.xml</value>
</constructor-arg>
<constructor-arg>
<value type="int">5000</value>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
Replace the entity id of SP metadata below:
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityId" value="replaceWithUniqueIdentifier"/>
<property name="extendedMetadata">
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="signMetadata" value="false"/>
<property name="idpDiscoveryEnabled" value="true"/>
</bean>
</property>
</bean>
I haven't been able to figure out the following:
All I have received is a url to adfs/../federationMetadata.xml, who is supposed to create the SP metadata?
Am I supposed to create SP metadata and provide to the client, to add it in adfs? Because, that's what I did using sample application. I added the generated metadata to ssocircle
Is my understanding, that point 1 would be adfs url, and point 2 will be SP entity id, correct?
I would be grateful if you could clarify the above to me, also if possible, point me to straightforward tutorial that helps in integrating SAML with Spring security enabled application as I haven't been able to find the same.
Many thanks
To make SAML between SP and IdP (ADFS) work, you have to mutually exchange metadata.
The ADFS metadata are available on the URL https://adfs-host/FederationMetadata/2007-06/FederationMetadata.xml and you can register them in your SP either with HTTPMetadataProvider, or download them and read them from classpath, or file system with ResourceBackedMetadataProvider.
For SP metadata, you have to configure MetadataGenerator (as you have it in your question) and then expose it via FilterChainProxy. Here is a Java configuration (it's equivalent for XML):
#Bean
public FilterChainProxy samlFilter() throws Exception {
List<SecurityFilterChain> chains = new ArrayList<SecurityFilterChain>();
chains.add(new DefaultSecurityFilterChain(
new AntPathRequestMatcher("/saml/metadata/**"), metadataDisplayFilter()));
return new FilterChainProxy(chains);
}
Than, you can access SP metadata on the URL https://sp-host/saml/metadata and register them on ADFS as a Relying Party Trust. Again, you can do this either via URL, or import data from the (downloaded) file.
Basically, you should be fine if you follow Spring Security SAML Reference Documentation which uses XML configuration. In case, you'll need to switch to Java configuration, you can find handy either referenced vdenotaris/spring-boot-security-saml-sample, or my working prototype sw-samuraj/blog-spring-security.
I used Spring SAML Sample application and followed the instructions. My configuration worked perfectly as expected, when SSOCircle IDP was used. However, I wanted to work this with ADFS. So, I followed the instructions on how to configure Spring SAML with ADFS. I got it through where when I access Spring SAML application is invoked, it displays the IDP Selection page with URL to adfs/services/trust. When I click on it, it prompts me for AD authentication, which is what I expected. But, when I provide the user id/password for the AD authentication, it process it and displays a message that reads "page can't be displayed".
On the address bar, the url to the page is displayed as:
https://localhost:8443/spring-security-saml2-sample/saml/login?idp=http%3A%2F%2FTest-DC.TEST.local%2Fadfs%2Fservices%2Ftrust.
Test-DC.TEST.local is my server where ADFS and AD is hosted.
There are no errors on the tomcat log or anywhere.
could someone who has setup Spring SAML with ADFS help here please?
Make sure that you're using SHA2 and not SHA1.
either override the afterPropertiesSet method:
public class SSOConfigBean
implements InitializingBean
{
private String signatureAlgorithmSHA = SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256;
private String digestAlgorithmSHA = SignatureConstants.ALGO_ID_DIGEST_SHA256;
#Override
public void afterPropertiesSet() throws Exception
{
BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
config.registerSignatureAlgorithmURI("RSA", signatureAlgorithmSHA);
config.setSignatureReferenceDigestMethod(digestAlgorithmSHA);
}
}
and add this to your securityContext:
<!-- setting encryption to SHA2 instead of default SHA1 -->
<bean class="path.to.SSOConfigBean"/>
Or update the securityContext you're using while setting your SP metadata as below:
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.MetadataGenerator">
<property name="entityId" value="urn:samltest"/>
<property name="extendedMetadata">
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="idpDiscoveryEnabled" value="false"/>
<property name="local" value="true"/>
<property name="signingAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
</bean>
</property>
</bean>
</constructor-arg>
</bean>
I am attempting to integrate spring-security-saml with an existing application to allow that application to act as a service provider.
Unfortunately, I can't seem to get the metadata filter to work. The webapp boots up without any fuss, but when I hit $contextPath/saml/metadata, I receive the following stack trace in my logs.
2014-10-24 13:52:38,779 54025 [1045652139#qtp-718389251-8] WARN org.mortbay.log - /sf/saml/metadata/
org.opensaml.saml2.metadata.provider.MetadataProviderException: No hosted service provider is configured and no alias was selected
at org.springframework.security.saml.context.SAMLContextProviderImpl.populateLocalEntity(SAMLContextProviderImpl.java:311) ~[spring-security-saml2-core
-1.0.0.RELEASE.jar:1.0.0.RELEASE]
at org.springframework.security.saml.context.SAMLContextProviderImpl.populateLocalContext(SAMLContextProviderImpl.java:216) ~[spring-security-saml2-cor
e-1.0.0.RELEASE.jar:1.0.0.RELEASE]
at org.springframework.security.saml.context.SAMLContextProviderImpl.getLocalEntity(SAMLContextProviderImpl.java:107) ~[spring-security-saml2-core-1.0.
0.RELEASE.jar:1.0.0.RELEASE]
at org.springframework.security.saml.metadata.MetadataDisplayFilter.processMetadataDisplay(MetadataDisplayFilter.java:114) ~[spring-security-saml2-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
at org.springframework.security.saml.metadata.MetadataDisplayFilter.doFilter(MetadataDisplayFilter.java:88) ~[spring-security-saml2-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) ~[spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) ~[spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:166) ~[spring-security-web-3.2.3.RELEASE.jar:3.2.3.RELEASE]
My metadata configuration is included below:
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg ref="metadataGenerator"/>
</bean>
<bean id="metadataGenerator" class="org.springframework.security.saml.metadata.MetadataGenerator">
<!--<property name="entityBaseURL" value="${env.shibboleth.entityBaseUrl"/>-->
<property name="bindingsSSO">
<list>
<value>redirect</value>
<value>artifact</value>
</list>
</property>
<property name="entityId" value="${env.shibboleth.entityId}"/>
<prop
</bean>
We are currently using:
spring version: 4.0.4.RELEASE
spring security version: 3.2.3.RELEASE
spring-security-saml2 version: 1.0.0.RELEASE
At this point, I'm largely at a loss, as we're not trying to do a multi-tennancy setup, which is the only place which alias is mentioned at length, and from what I can see, the metadataGenerator defines a service provider?
The metadataGeneratorFilter needs to be executed before invocation of the MetadataDisplayFilter, make sure to include the following declaration in your <security:http> element:
<security:custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
Also, your value for entityId seems to suggest that you are using same entityId for both your IDP (Shibboleth) and SP (Spring SAML application). Make sure that the value is unique for both of the entities.
I've got application with spring security SAML filters. There is configuration with ADFS 2.0. Server is standing on machine out of domain. I try to login on my App on domain account of user (but window to input domain user principals is displayed). Is there possibility to config this to autologin for user on which domain user we're logged on windows?
Thanks a log.
You can configure custom authnContext sent in your SAML request by changing bean samlEntryPoint in the following way:
<bean id="samlEntryPoint" class="org.springframework.security.saml.SAMLEntryPoint">
<property name="defaultProfileOptions">
<bean class="org.springframework.security.saml.websso.WebSSOProfileOptions">
<property name="authnContexts"
value="urn:federation:authentication:windows"/>
</bean>
</property>
</bean>
I have Spring Security configured to authenticate against LDAP server.
<security:authentication-manager >
<security:ldap-authentication-provider user-dn-pattern="uid={0}" />
</security:authentication-manager>
After authentication I want to load roles from local database for the same user. How can I load local database roles using "ldap-authentication-provider"?
If I add the second authentication provider as below:
<security:authentication-manager >
<security:ldap-authentication-provider user-dn-pattern="uid={0}" />
<security:authentication-provider ref="daoAuthenticationProvider" />
</security:authentication-manager>
daoAuthenticationProvider added, but Spring does not use the second provider when first auth provider authenticates the user. Only if the first auth provider fails to authenticate it goes next in the list.
So basically look like we have to customize
<security:ldap-authentication-provider user-dn-pattern="uid={0}" />
to load ROLEs from local database.
Any suggestions? How should this be implemented?
An authentication provider must deliver a fully populated authentication token on successfull authentication, so it's not possible to use one provider to check the user's credentials, and another one to assign authorities (roles) to it.
You can however customize an ldap auth provider to fetch user roles from database instead of the default behaviour (searching for the user's groups in ldap). The LdapAuthenticationProvider has two strategies injected: one that performs the authentication itself (LdapAuthenticator), and another one that fetches the user's authorities (LdapAuthoritiesPopulator). You can achieve your requirements if you supply an LdapAuthoritiesPopulator implementation that loads roles from database. In case you already have a UserDetailsService working against the database, you can easily integrate that by wrapping it in a UserDetailsServiceLdapAuthoritiesPopulator and injecting it in the LdapAuthenticationProvider.
Since this configuration is rather uncommon, the security xml namespace doesn't provide tags/attributes to set it up, but the raw bean config isn't too complicated. Here is the outline:
1) I suppose you have an ldap-server somewhere in your config. It's important to assign and id to it, which will allow us to reference it later.
<security:ldap-server url="..." id="ldapServer" .../>
2) From the authentication-manager section, you will only refer to the customized provider:
<security:authentication-manager>
<security:authentication-provider ref="customLdapAuthProvider"/>
</security:authentication-manager>
3) Now, the essential part:
<bean id="customLdapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg name="authenticator">
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg name="contextSource" ref="ldapServer"/>
<property name="userDnPatterns">
<list>
<value>uid={0}</value>
</list>
</property>
</bean>
</constructor-arg>
<constructor-arg name="authoritiesPopulator">
<bean class="org.springframework.security.ldap.authentication.UserDetailsServiceLdapAuthoritiesPopulator">
<constructor-arg name="userService" ref="userService"/>
</bean>
</constructor-arg>
</bean>
The authenticator is basically the same as the one that would be created by the namespace config. (Note the contextSource attribute referencing the ldap server.)
The authoritiesPopulator is a simple wrapper around your userService implementation which is supposed to be defined somewhere in your config.