com.github.ulisesbocchio.spring.boot.security.saml.configuration.SAMLServiceProviderSecurityConfiguration Maven / Gradle / Ivy
Show all versions of spring-boot-security-saml Show documentation
package com.github.ulisesbocchio.spring.boot.security.saml.configuration;
import com.github.ulisesbocchio.spring.boot.security.saml.bean.SAMLConfigurerBean;
import com.github.ulisesbocchio.spring.boot.security.saml.bean.override.LocalExtendedMetadata;
import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderBuilder;
import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderConfigurer;
import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderConfigurerAdapter;
import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderEndpoints;
import com.github.ulisesbocchio.spring.boot.security.saml.properties.SAMLSSOProperties;
import org.assertj.core.util.Lists;
import org.opensaml.xml.parse.ParserPool;
import org.opensaml.xml.parse.StaticBasicParserPool;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.io.ResourceLoader;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.saml.SAMLAuthenticationProvider;
import org.springframework.security.saml.SAMLBootstrap;
import org.springframework.security.saml.context.SAMLContextProvider;
import org.springframework.security.saml.key.KeyManager;
import org.springframework.security.saml.log.SAMLDefaultLogger;
import org.springframework.security.saml.log.SAMLLogger;
import org.springframework.security.saml.metadata.ExtendedMetadata;
import org.springframework.security.saml.metadata.MetadataGenerator;
import org.springframework.security.saml.metadata.MetadataManager;
import org.springframework.security.saml.parser.ParserPoolHolder;
import org.springframework.security.saml.processor.SAMLProcessor;
import org.springframework.security.saml.websso.*;
import java.util.Collections;
import java.util.List;
import static com.github.ulisesbocchio.spring.boot.security.saml.util.FunctionalUtils.unchecked;
/**
* Spring Security configuration entry point for the Service Provider. This configuration class basically collects
* all relevant beans present in the application context to initialize and configure all {@link
* ServiceProviderConfigurer}
* present in the context. Usually one {@link ServiceProviderConfigurer} is enough and preferably one that extends
* {@link ServiceProviderConfigurerAdapter} which provides empty implementations and subclasses can implement only the
* relevant method(s) for the purpose of the current application.
*
* All {@code required=false} autowired beans can be provided as beans by the user instead of using the
* {@link ServiceProviderConfigurer} DSL.
*
* @author Ulises Bocchio
*/
@Configuration
@EnableConfigurationProperties(SAMLSSOProperties.class)
public class SAMLServiceProviderSecurityConfiguration implements InitializingBean {
@Autowired
private SAMLSSOProperties sAMLSsoProperties;
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private SAMLLogger samlLogger;
@Autowired(required = false)
private ExtendedMetadata extendedMetadata;
@Autowired(required = false)
private LocalExtendedMetadata localExtendedMetadata;
@Autowired(required = false)
private SAMLContextProvider samlContextProvider;
@Autowired(required = false)
private KeyManager keyManager;
@Autowired(required = false)
private MetadataManager metadataManager;
@Autowired(required = false)
private MetadataGenerator metadataGenerator;
@Autowired(required = false)
private SAMLProcessor samlProcessor;
@Autowired(required = false)
private WebSSOProfileConsumer webSSOProfileConsumer;
@Autowired(required = false)
private WebSSOProfileConsumerHoKImpl hokWebSSOProfileConsumer;
@Autowired(required = false)
private WebSSOProfile webSSOProfile;
@Autowired(required = false)
private WebSSOProfileECPImpl ecpProfile;
@Autowired(required = false)
private WebSSOProfileHoKImpl hokWebSSOProfile;
@Autowired(required = false)
private SingleLogoutProfile sloProfile;
@Autowired(required = false)
private SAMLAuthenticationProvider samlAuthenticationProvider;
@Autowired(required = false)
List serviceProviderConfigurers = Lists.newArrayList();
@Autowired(required = false)
SAMLConfigurerBean samlConfigurerBean;
@Autowired(required = false)
ApplicationEventPublisher eventPublisher;
@Autowired
ServiceProviderBuilder serviceProviderBuilder;
@Bean
@ConditionalOnMissingBean
public static SAMLBootstrap sAMLBootstrap() {
return new SAMLBootstrap();
}
@Bean
@ConditionalOnMissingBean
public ParserPoolHolder parserPoolHolder() {
return new ParserPoolHolder();
}
@Bean(initMethod = "initialize")
@ConditionalOnMissingBean
public ParserPool parserPool() {
return new StaticBasicParserPool();
}
@Bean
@ConditionalOnMissingBean
public SAMLLogger samlLogger() {
return new SAMLDefaultLogger();
}
@Bean
public static ServiceProviderBuilder serviceProviderBuilder() {
return new ServiceProviderBuilder();
}
/**
* Default Web Security Configurer that delegates configuration of the service provider to {@link
* ServiceProviderConfigurer}
*/
@ConditionalOnMissingBean(SAMLConfigurerBean.class)
@Configuration
static class SAMLWebSecurityConfigurer extends WebSecurityConfigurerAdapter implements Ordered {
@Autowired(required = false)
@SuppressWarnings("SpringJavaAutowiringInspection")
private List serviceProviderConfigurers = Collections.emptyList();
@Override
public void configure(WebSecurity web) throws Exception {
serviceProviderConfigurers.forEach(unchecked(c -> c.configure(web)));
}
@Bean
SAMLConfigurerBean saml() {
return new SAMLConfigurerBean();
}
@ConditionalOnMissingBean
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(null);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.httpBasic()
.disable()
.csrf()
.disable()
.anonymous()
.and()
.apply(saml())
.serviceProvider(serviceProviderConfigurers)
.http()
.authorizeRequests()
.requestMatchers(saml().endpointsMatcher()).permitAll();
serviceProviderConfigurers.forEach(unchecked(spc -> spc.configure(http)));
http
.authorizeRequests()
.anyRequest()
.authenticated();
// @formatter:on
}
@Override
public int getOrder() {
return -17;
}
}
@Override
public void afterPropertiesSet() {
//All existing beans are thrown as shared objects to the ServiceProviderSecurityBuilder, which will wire all
//beans/objects related to spring security SAML.
serviceProviderBuilder.setSharedObject(ParserPool.class, ParserPoolHolder.getPool());
serviceProviderBuilder.setSharedObject(WebSSOProfileConsumerImpl.class, (WebSSOProfileConsumerImpl) webSSOProfileConsumer);
serviceProviderBuilder.setSharedObject(WebSSOProfileConsumerHoKImpl.class, hokWebSSOProfileConsumer);
serviceProviderBuilder.setSharedObject(ServiceProviderEndpoints.class, new ServiceProviderEndpoints());
serviceProviderBuilder.setSharedObject(ResourceLoader.class, resourceLoader);
serviceProviderBuilder.setSharedObject(SAMLSSOProperties.class, sAMLSsoProperties);
serviceProviderBuilder.setSharedObject(ExtendedMetadata.class, extendedMetadata);
serviceProviderBuilder.setSharedObject(LocalExtendedMetadata.class, localExtendedMetadata);
serviceProviderBuilder.setSharedObject(SAMLAuthenticationProvider.class, samlAuthenticationProvider);
serviceProviderBuilder.setSharedObject(SAMLContextProvider.class, samlContextProvider);
serviceProviderBuilder.setSharedObject(KeyManager.class, keyManager);
serviceProviderBuilder.setSharedObject(MetadataManager.class, metadataManager);
serviceProviderBuilder.setSharedObject(MetadataGenerator.class, metadataGenerator);
serviceProviderBuilder.setSharedObject(SAMLProcessor.class, samlProcessor);
serviceProviderBuilder.setSharedObject(WebSSOProfile.class, webSSOProfile);
serviceProviderBuilder.setSharedObject(WebSSOProfileECPImpl.class, ecpProfile);
serviceProviderBuilder.setSharedObject(WebSSOProfileHoKImpl.class, hokWebSSOProfile);
serviceProviderBuilder.setSharedObject(SingleLogoutProfile.class, sloProfile);
serviceProviderBuilder.setSharedObject(WebSSOProfileConsumer.class, webSSOProfileConsumer);
serviceProviderBuilder.setSharedObject(WebSSOProfileConsumerHoKImpl.class, hokWebSSOProfileConsumer);
serviceProviderBuilder.setSharedObject(SAMLLogger.class, samlLogger);
serviceProviderBuilder.setSharedObject(ApplicationEventPublisher.class, eventPublisher);
}
}