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);