diff --git a/CHANGELOG.md b/CHANGELOG.md index 718cd8d..600861e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 0.7.0 - 2017-11-28 + +* Dropped autowired `Environment` from `SAMLWebSecurityConfigurerAdapter` and replaced with `ApplicationContext` to allow concrete class to access any Spring beans instead of just `Environment` to configure the security. This will also prevent any lifecycle or circular dependency problems when trying to autowire beans in concrete class. +* Replaced `@PostContruct` with `@Bean` for `SAMLWebSecurityConfigurerAdapter.socketFactoryInitialization()`. + ## 0.6.0 - 2016-07-18 * Helper class `JndiBackedKeystoreService` to retrieve keystore info from JNDI value with following format: `jks-path,alias,storepass,keypass` diff --git a/README.md b/README.md index be80ac1..196629c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Tested against IdP's environments:- com.github.choonchernlim spring-security-adfs-saml2 - 0.6.0 + 0.7.0 ``` @@ -64,7 +64,9 @@ keytool -importcert \ ## Usage -### Configuration Example +### Simplest Configuration + +If you are configuring for one IDP server, the easiest approach is to hardcode all the SAML config in the `@Configuration` file. ```java // Create a Java-based Spring configuration that extends SAMLWebSecurityConfigurerAdapter. @@ -117,7 +119,82 @@ class AppSecurityConfig extends SAMLWebSecurityConfigurerAdapter { } ``` -### Mocking Security by Harcdoding a Given User for Rapid App Development +### Environment Properties Driven Configuration + +If you don't want to use `@Profile` to configure environment-specific security, you may pass the configuration values through environment properties. + +To prevent lifecycle loading or circular dependency issues, instead of autowiring `Environment` into the concrete class, use the given autowired `applicationContext` to get hold of the Spring bean. + +```java +@Configuration +@EnableWebSecurity +class AppSecurityConfig extends SAMLWebSecurityConfigurerAdapter { + + @Override + protected SAMLConfigBean samlConfigBean() { + final Environment env = applicationContext.getBean(Environment.class); + + return new SAMLConfigBeanBuilder() + .withIdpServerName(env.getProperty("idpServerName")) + .withSpServerName(env.getProperty("spServerName")) + .withSpContextPath(env.getProperty("spContextPath")) + .withKeystoreResource(new DefaultResourceLoader().getResource(env.getProperty("keystoreResource"))) + .withKeystorePassword(env.getProperty("keystorePassword")) + .withKeystoreAlias(env.getProperty("keystoreAlias")) + .withKeystorePrivateKeyPassword(env.getProperty("keystorePrivateKeyPassword")) + .withSuccessLoginDefaultUrl(env.getProperty("successLoginDefaultUrl")) + .withSuccessLogoutUrl(env.getProperty("successLogoutUrl")) + .withStoreCsrfTokenInCookie(env.getProperty("storeCsrfTokenInCookie")) + .build(); + } + + ... +} +``` + +### Database Driven Configuration + +You may also configure `SAMLConfigBean` by retrieving the configuration values from database. + +Let's assume you have the following Spring JPA repository:- + +```java +public interface SecurityConfigRepository extends JpaRepository { + SecurityConfigEntity findByEnvironment(String environment); +} +``` + +To prevent lifecycle loading or circular dependency issues, instead of autowiring `SecurityConfigRepository` into the concrete class, use the given autowired `applicationContext` to get hold of the Spring repository bean. + +```java +@Configuration +@EnableWebSecurity +class AppSecurityConfig extends SAMLWebSecurityConfigurerAdapter { + + @Override + protected SAMLConfigBean samlConfigBean() { + final SecurityConfigRepository repository = applicationContext.getBean(SecurityConfigRepository.class); + final SecurityConfigEntity entity = repository.findByEnvironment("dev"); + + return new SAMLConfigBeanBuilder() + .withIdpServerName(entity.getIdpServerName()) + .withSpServerName(entity.getSpServerName()) + .withSpContextPath(entity.getSpContextPath()) + .withKeystoreResource(new DefaultResourceLoader().getResource(entity.getKeystoreResource())) + .withKeystorePassword(entity.getKeystorePassword()) + .withKeystoreAlias(entity.getKeystoreAlias()) + .withKeystorePrivateKeyPassword(entity.getKeystorePrivateKeyPassword()) + .withSuccessLoginDefaultUrl(entity.getSuccessLoginDefaultUrl()) + .withSuccessLogoutUrl(entity.getSuccessLogoutUrl()) + .withStoreCsrfTokenInCookie(entity.getStoreCsrfTokenInCookie()) + .build(); + } + + ... +} +``` + +### Mocking Security by Hardcoding a Given User for Rapid App Development ```java @Override diff --git a/pom.xml b/pom.xml index c3ca8e3..7d7a116 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ spring-security-adfs-saml2 - 0.6.0 + 0.7.0 jar Spring Security ADFS SAML2 diff --git a/src/main/java/com/github/choonchernlim/security/adfs/saml2/SAMLWebSecurityConfigurerAdapter.java b/src/main/java/com/github/choonchernlim/security/adfs/saml2/SAMLWebSecurityConfigurerAdapter.java index d0df233..d6af629 100644 --- a/src/main/java/com/github/choonchernlim/security/adfs/saml2/SAMLWebSecurityConfigurerAdapter.java +++ b/src/main/java/com/github/choonchernlim/security/adfs/saml2/SAMLWebSecurityConfigurerAdapter.java @@ -15,8 +15,8 @@ import org.opensaml.xml.parse.StaticBasicParserPool; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.MethodInvokingFactoryBean; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; -import org.springframework.core.env.Environment; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -78,7 +78,6 @@ import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import javax.annotation.PostConstruct; import java.util.Timer; /** @@ -88,10 +87,10 @@ public abstract class SAMLWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { /** - * Provides an opportunity for child class to access Spring environment, if needed. + * Provides an opportunity for child class to access any Spring beans, if needed. */ @Autowired - protected Environment env; + protected ApplicationContext applicationContext; @Autowired private SAMLAuthenticationProvider samlAuthenticationProvider; @@ -365,7 +364,7 @@ public Protocol protocol() { } // Configure TLSProtocolConfigurer - @PostConstruct + @Bean public MethodInvokingFactoryBean socketFactoryInitialization() { MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean(); methodInvokingFactoryBean.setTargetClass(Protocol.class);