Skip to content

Instantly share code, notes, and snippets.

@geesen
Created July 8, 2015 09:19
Show Gist options
  • Save geesen/e9c56de6c463152ffc47 to your computer and use it in GitHub Desktop.
Save geesen/e9c56de6c463152ffc47 to your computer and use it in GitHub Desktop.
Example of SecurityConfiguration for Spring (JHipster) and LDAP
package de.indivon.example.config;
import java.util.ArrayList;
import java.util.Collection;
import javax.inject.Inject;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.ldap.core.support.LdapContextSource;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
import org.springframework.security.ldap.search.LdapUserSearch;
import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator;
import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.csrf.CsrfFilter;
import de.indivon.example.config.properties.LdapProperties;
import de.indivon.example.security.AjaxAuthenticationFailureHandler;
import de.indivon.example.security.AjaxAuthenticationSuccessHandler;
import de.indivon.example.security.AjaxLogoutSuccessHandler;
import de.indivon.example.security.AuthoritiesConstants;
import de.indivon.example.security.CustomLdapUserDetailsService;
import de.indivon.example.security.Http401UnauthorizedEntryPoint;
import de.indivon.example.web.filter.CsrfCookieGeneratorFilter;
@Configuration
@EnableConfigurationProperties
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@AutoConfigureBefore(org.activiti.spring.boot.SecurityAutoConfiguration.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Inject
private Environment env;
@Inject
private AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler;
@Inject
private AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler;
@Inject
private AjaxLogoutSuccessHandler ajaxLogoutSuccessHandler;
@Inject
private Http401UnauthorizedEntryPoint authenticationEntryPoint;
@Inject
private RememberMeServices rememberMeServices;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public CustomLdapUserDetailsService customLdapUserDetailsService() {
CustomLdapUserDetailsService uds = new CustomLdapUserDetailsService(ldapUserSearch(), ldapAuthoritiesPopulator());
uds.setUserDetailsMapper(userDetailsContextMapper());
return uds;
}
@Bean
public UserDetailsService userDetailsService() {
return customLdapUserDetailsService();
}
@Bean
public UserDetailsContextMapper userDetailsContextMapper() {
return new UserDetailsContextMapper() {
@Override
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
}
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
grantedAuthorities.addAll(authorities);
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(AuthoritiesConstants.USER);
grantedAuthorities.add(grantedAuthority);
return new org.springframework.security.core.userdetails.User(username, "1", grantedAuthorities);
}
};
}
@Bean
public LdapAuthoritiesPopulator ldapAuthoritiesPopulator() {
DefaultLdapAuthoritiesPopulator authoritiesPopulator = new DefaultLdapAuthoritiesPopulator(contextSource(), ldapProperties().getGroupSearchBase());
authoritiesPopulator.setGroupRoleAttribute(ldapProperties().getGroupRoleAttribute());
authoritiesPopulator.setGroupSearchFilter(ldapProperties().getGroupSearchFilter());
return authoritiesPopulator;
}
@Bean
public LdapUserSearch ldapUserSearch() {
String searchBase = ldapProperties().getUserSearchBase();
String searchFilter = ldapProperties().getUserSearchFilter();
BaseLdapPathContextSource contextSource = contextSource();
return new FilterBasedLdapUserSearch(searchBase, searchFilter, contextSource);
}
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userDetailsContextMapper(userDetailsContextMapper())
.ldapAuthoritiesPopulator(ldapAuthoritiesPopulator())
.userSearchBase(ldapProperties().getUserSearchBase())
.userSearchFilter(ldapProperties().getUserSearchFilter())
.contextSource(contextSource());
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/scripts/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/assets/**")
.antMatchers("/swagger-ui/**")
.antMatchers("/test/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/websocket/**").and()
.addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class).exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint).and()
.rememberMe()
.rememberMeServices(rememberMeServices)
.rememberMeParameter("remember-me")
.key(env.getProperty("jhipster.security.rememberme.key")).and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/api/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password").permitAll().and()
.logout()
.logoutUrl("/api/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.logoutSuccessUrl("/login")
.deleteCookies("JSESSIONID").permitAll().and()
.headers()
.frameOptions().disable().and()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/account/reset_password/init").permitAll()
.antMatchers("/api/account/reset_password/finish").permitAll()
.antMatchers("/api/logs/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api/**").authenticated()
.antMatchers("/websocket/tracker").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/websocket/**").permitAll()
.antMatchers("/metrics/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/health/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/dump/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/shutdown/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/beans/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/configprops/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/info/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/autoconfig/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/env/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api-docs/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/activiti/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/protected/**").authenticated()
.antMatchers("/index.html").permitAll();
}
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
@Bean
public LdapTemplate ldapTemplate() {
return new LdapTemplate(contextSource());
}
@Bean LdapProperties ldapProperties(){
return new LdapProperties();
}
@Bean
public LdapContextSource contextSource() {
LdapContextSource contextSource = new LdapContextSource();
contextSource.setUrl(ldapProperties().getUrl());
contextSource.setBase(ldapProperties().getBase());
contextSource.setUserDn(ldapProperties().getUserDn());
contextSource.setPassword(ldapProperties().getPassword());
return contextSource;
}
}
@iBaribal
Copy link

iBaribal commented Jun 6, 2017

Hi!

I would also like to see CustomLdapUserDetailsService.java class. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment