package de.rwth.idsg.bikeman.config; import de.rwth.idsg.bikeman.security.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.data.repository.query.spi.EvaluationContextExtension; import org.springframework.data.repository.query.spi.EvaluationContextExtensionSupport; import org.springframework.http.HttpMethod; import org.springframework.security.access.expression.SecurityExpressionRoot; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; 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.context.SecurityContextHolder; 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.web.authentication.RememberMeServices; import org.springframework.security.web.header.writers.XXssProtectionHeaderWriter; import javax.inject.Inject; @Configuration @EnableWebSecurity 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 UserDetailsService userDetailsService; @Inject private RememberMeServices rememberMeServices; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Inject public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userDetailsService) .passwordEncoder(passwordEncoder()); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring() .antMatchers("/scripts/**/*.{js,html}") .antMatchers("/bower_components/**") .antMatchers("/i18n/**") .antMatchers("/fonts/**") .antMatchers("/images/**") .antMatchers("/views/**") .antMatchers("/styles/**") .antMatchers("/swagger-ui/**") .antMatchers("/test/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http //.addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class) .exceptionHandling() .authenticationEntryPoint(authenticationEntryPoint) .and() .rememberMe() .rememberMeServices(rememberMeServices) .key(env.getProperty("jhipster.security.rememberme.key")) .and() .formLogin() .loginProcessingUrl("/api/authentication") .successHandler(ajaxAuthenticationSuccessHandler) .failureHandler(ajaxAuthenticationFailureHandler) .usernameParameter("j_username") .passwordParameter("j_password") .permitAll() .and() .logout() .logoutUrl("/api/logout") .logoutSuccessHandler(ajaxLogoutSuccessHandler) .deleteCookies("JSESSIONID") .permitAll() .and() .csrf() .disable() .headers() .frameOptions() .disable() .authorizeRequests() .antMatchers("/api/register").permitAll() .antMatchers("/api/activate").permitAll() .antMatchers("/api/authenticate").permitAll() .antMatchers("/api/logs/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/api/**").authenticated() .antMatchers("/api/authenticate").permitAll() .antMatchers("/psi*").hasIpAddress("10.10.0.0/16") // Restricted psi access!! .antMatchers("/api/logs/**").hasAnyAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/api/errorHistory").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/audits*").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/audits/**").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/customers*").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/customers/**").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/managers*").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/api/managers/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/api/pedelecs*").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/pedelecs/**").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/stations*").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/stations/**").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/transactions*").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/transactions/**").hasAuthority(AuthoritiesConstants.MANAGER) .antMatchers("/api/cardaccount*").hasAnyAuthority(AuthoritiesConstants.MAJOR_CUSTOMER, AuthoritiesConstants.MANAGER) .antMatchers("/api/cardaccount/**").hasAnyAuthority(AuthoritiesConstants.MAJOR_CUSTOMER, AuthoritiesConstants.MANAGER) .antMatchers(HttpMethod.OPTIONS, "/app/**").permitAll() .antMatchers(HttpMethod.GET, "/app/stations").permitAll() .antMatchers(HttpMethod.GET, "/app/stations/*").permitAll() .antMatchers(HttpMethod.GET, "/app/stations/*/slots").permitAll() .antMatchers(HttpMethod.POST, "/app/customer").permitAll() .antMatchers(HttpMethod.POST, "/app/customer/passwordreset").permitAll() .antMatchers(HttpMethod.GET, "/app/customer/passwordreset/**").permitAll() .antMatchers(HttpMethod.POST, "/app/customer/passwordreset-request").permitAll() .antMatchers("/app/**").authenticated() .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("/protected/**").authenticated(); } @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) private static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration { } /** * This allows SpEL support in Spring Data JPA @Query definitions. * <p> * See https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions */ @Bean EvaluationContextExtension securityExtension() { return new EvaluationContextExtensionSupport() { @Override public String getExtensionId() { return "security"; } @Override public SecurityExpressionRoot getRootObject() { return new SecurityExpressionRoot(SecurityContextHolder.getContext().getAuthentication()) { }; } }; } }