Skip to content

Commit

Permalink
Make Spring Security configurable on servlet basis (frankframework#3991)
Browse files Browse the repository at this point in the history
  • Loading branch information
nielsm5 authored Nov 16, 2022
1 parent a853196 commit bad1fb5
Show file tree
Hide file tree
Showing 22 changed files with 900 additions and 665 deletions.
5 changes: 5 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,11 @@
<artifactId>spring-security-config</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>${spring-security.version}</version>
</dependency>
<!-- not yet used, note that it depends on Spring 4.3.30
<dependency>
<groupId>org.springframework.security.oauth</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,130 +15,29 @@
*/
package nl.nn.adapterframework.lifecycle;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.MappableAttributesRetriever;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService;
import org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource;
import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter;
import org.springframework.security.web.authentication.preauth.j2ee.WebXmlMappableAttributesRetriever;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;

import lombok.Setter;
import nl.nn.adapterframework.util.SpringUtils;


/**
* Programmatic configuration of the spring security configuration: webSecurityConfig.xml
*
* <pre><code>
*
* <http use-expressions="true" realm="Frank" authentication-manager-ref="authenticationManager" entry-point-ref="403EntryPoint" pattern="/**">
* <security:csrf disabled="true" />
* <security:headers>
* <security:frame-options policy="SAMEORIGIN" />
* <security:content-type-options disabled="true" />
* </security:headers>
* <security:custom-filter position="PRE_AUTH_FILTER" ref="jeePreAuthenticatedFilter" />
* <security:logout />
* </http>
*
* <authentication-manager alias="authenticationManager">
* <security:authentication-provider ref="j2eeAuthenticationProvider" />
* </authentication-manager>
*
* </code></pre>
*/
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(jsr250Enabled = true, prePostEnabled = false)
public class HttpSecurityConfigurer implements ApplicationContextAware, InitializingBean {
@Order(Ordered.LOWEST_PRECEDENCE)
@IbisInitializer
@EnableWebSecurity //Enables Spring Security (classpath)
@EnableMethodSecurity(jsr250Enabled = true, prePostEnabled = false) //Enables JSR 250 (JAX-RS) annotations
public class HttpSecurityConfigurer implements InitializingBean {

private static final String ROLE_PREFIX = "ROLE_"; //see AuthorityAuthorizationManager#ROLE_PREFIX
private @Setter ApplicationContext applicationContext;
private @Setter @Autowired ServletManager servletManager;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
if(servletManager.isWebSecurityEnabled()) {
http.requestMatcher(AnyRequestMatcher.INSTANCE);
AuthenticationManager authManager = getAuthenticationManager(http);
http.addFilter(getProcessingFilter(authManager));
http.authenticationManager(authManager);
} else {
http.anonymous().authorities(getDefaultAuthorities());
}

http.headers().frameOptions().sameOrigin();
http.csrf().disable();
http.logout();
return http.build();
}

private List<GrantedAuthority> getDefaultAuthorities() {
List<String> ibisRoles = servletManager.getDefaultIbisRoles();
List<GrantedAuthority> grantedAuthorities = new ArrayList<>(ibisRoles.size());
for (String role : ibisRoles) {
grantedAuthorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + role));
}
return grantedAuthorities;
}

//see AuthenticationManagerFactoryBean
private AuthenticationManager getAuthenticationManager(HttpSecurity http) {
AuthenticationProvider provider = getAuthenticationProvider(http);
return new ProviderManager(Arrays.<AuthenticationProvider>asList(provider));
}

//see JeeConfigurer.init
private PreAuthenticatedAuthenticationProvider getAuthenticationProvider(HttpSecurity http) {
PreAuthenticatedAuthenticationProvider authenticationProvider = new PreAuthenticatedAuthenticationProvider();
authenticationProvider.setPreAuthenticatedUserDetailsService(new PreAuthenticatedGrantedAuthoritiesUserDetailsService());
http.authenticationProvider(authenticationProvider).setSharedObject(AuthenticationEntryPoint.class, new Http403ForbiddenEntryPoint());
return authenticationProvider;
}

private J2eePreAuthenticatedProcessingFilter getProcessingFilter(AuthenticationManager authManager) {
J2eePreAuthenticatedProcessingFilter filter = new J2eePreAuthenticatedProcessingFilter();
filter.setAuthenticationDetailsSource(getAuthenticationDetailsSource());
filter.setAuthenticationManager(authManager);
return filter;
}

private J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource getAuthenticationDetailsSource() {
J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource authenticationDetailSource = new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource();
authenticationDetailSource.setMappableRolesRetriever(getWebXmlSecurityRoles());
return authenticationDetailSource;
}

private MappableAttributesRetriever getWebXmlSecurityRoles() {
return SpringUtils.createBean(applicationContext, WebXmlMappableAttributesRetriever.class);
}

@Override
public void afterPropertiesSet() throws Exception {
if(servletManager == null) {
throw new IllegalStateException("unable to initialize Spring Security, ServletManager not set");
}

servletManager.startAuthenticators();
}
}
Loading

0 comments on commit bad1fb5

Please sign in to comment.