SecurityConfig.java
/*
* +====================================================================+
* | Copyright (C) 2015 Rochester Institute of Technology, |
* | 103 Lomb Memorial Drive, Rochester, NY - 14623 |
* | All Rights Reserved. |
* +====================================================================+
* FILENAME
* SecurityConfig.java
*
* AUTHOR
* @author Khanh Ho (kchisd at rit.edu)
*
* =====================================================================
*/
package edu.rit.coopeval.security;
import java.util.LinkedHashMap;
import java.util.Map;
import edu.rit.coopeval.security.sso.ShibbolethAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.*;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
@Autowired
private AuthenticationSettings props;
@Autowired
private Map<String, UserDetailsService> uds;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
if (props.getShib().isEnabled()) {
logger.debug("Adding Shibboleth authentication filter");
http.addFilter(shibFilter());
}
http.formLogin().loginPage("/login").usernameParameter("email").passwordParameter("password")
.and().exceptionHandling()
.authenticationEntryPoint(delegatingAep()).accessDeniedPage("/error/unauthorized")
.and().authorizeRequests()
.antMatchers("/login**", "/error**", "/libs**", "/api/testing/**").permitAll()
.anyRequest().authenticated()
.and().csrf().disable();
}
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
if (props.getShib().isEnabled()) {
logger.debug("Setting up Shibboleth authentication provider");
auth.authenticationProvider(preauthAuthProvider());
}
auth.userDetailsService(uds.get("dbUserDetailsService")).passwordEncoder(passwordEncoder);
}
@Bean
public PreAuthenticatedAuthenticationProvider preauthAuthProvider() {
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(userDetailsServiceWrapper());
return provider;
}
private UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> userDetailsServiceWrapper() {
UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> wrapper = new UserDetailsByNameServiceWrapper<>();
wrapper.setUserDetailsService(uds.get("shibUserDetailsService"));
return wrapper;
}
private ShibbolethAuthenticationFilter shibFilter() throws Exception {
ShibbolethAuthenticationFilter filter = new ShibbolethAuthenticationFilter();
filter.setShibPath(props.getShib().getPath());
filter.setAuthenticationManager(authenticationManager());
return filter;
}
private AuthenticationEntryPoint delegatingAep() {
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints = new LinkedHashMap<>();
entryPoints.put(new AntPathRequestMatcher(props.getShib().getPath()), new Http403ForbiddenEntryPoint());
entryPoints.put(new AntPathRequestMatcher("/**"), new LoginUrlAuthenticationEntryPoint("/login"));
return new DelegatingAuthenticationEntryPoint(entryPoints);
}
}