Skip to content

Commit

Permalink
Merge pull request #11 from choonchernlim/feature/db-driven
Browse files Browse the repository at this point in the history
Feature/db driven
  • Loading branch information
choonchernlim authored Nov 28, 2017
2 parents 05926fd + 4d77f19 commit 03609cb
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 9 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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`
Expand Down
83 changes: 80 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Tested against IdP's environments:-
<dependency>
<groupId>com.github.choonchernlim</groupId>
<artifactId>spring-security-adfs-saml2</artifactId>
<version>0.6.0</version>
<version>0.7.0</version>
</dependency>
```

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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, Long> {
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
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>

<artifactId>spring-security-adfs-saml2</artifactId>
<version>0.6.0</version>
<version>0.7.0</version>
<packaging>jar</packaging>

<name>Spring Security ADFS SAML2</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

/**
Expand All @@ -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;
Expand Down Expand Up @@ -365,7 +364,7 @@ public Protocol protocol() {
}

// Configure TLSProtocolConfigurer
@PostConstruct
@Bean
public MethodInvokingFactoryBean socketFactoryInitialization() {
MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
methodInvokingFactoryBean.setTargetClass(Protocol.class);
Expand Down

0 comments on commit 03609cb

Please sign in to comment.