/* * Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET) * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package ch.ethz.seb.sebserver; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; 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.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; /** This is the overall seb-server Spring web-configuration that is loaded for all profiles. * Defines some overall web-security beans needed on both -- web-service and web-gui -- profiles */ @Configuration @WebServiceProfile @GuiProfile @RestController @Order(6) public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ErrorController { @Value("${sebserver.webservice.api.redirect.unauthorized}") private String unauthorizedRedirect; /** Spring bean name of user password encoder */ public static final String USER_PASSWORD_ENCODER_BEAN_NAME = "userPasswordEncoder"; /** Spring bean name of client (application) password encoder */ public static final String CLIENT_PASSWORD_ENCODER_BEAN_NAME = "clientPasswordEncoder"; /** Password encoder used for user passwords (stronger protection) */ @Bean(USER_PASSWORD_ENCODER_BEAN_NAME) public PasswordEncoder userPasswordEncoder() { return new BCryptPasswordEncoder(8); } /** Password encode used for client (application) passwords */ @Bean(CLIENT_PASSWORD_ENCODER_BEAN_NAME) public PasswordEncoder clientPasswordEncoder() { return new BCryptPasswordEncoder(4); } @Override public void configure(final WebSecurity web) { web .ignoring() .antMatchers("/error"); } @Override public void configure(final HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .antMatcher("/**") .authorizeRequests() .anyRequest() .authenticated() .and() .exceptionHandling() .authenticationEntryPoint( new AuthenticationEntryPoint() { @Override public void commence( final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException, ServletException { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.sendRedirect(WebSecurityConfig.this.unauthorizedRedirect); } }) .and() .formLogin().disable() .httpBasic().disable() .logout().disable() .headers().frameOptions().disable() .and() .csrf().disable(); } @RequestMapping("/error") public void handleError(final HttpServletResponse response) throws IOException { response.setStatus(HttpStatus.NOT_FOUND.value()); response.sendRedirect(this.unauthorizedRedirect); } @Override public String getErrorPath() { return "/error"; } }