apply Spring's actuator
This commit is contained in:
parent
5032e39352
commit
e2b93e5529
5 changed files with 74 additions and 14 deletions
|
@ -32,7 +32,7 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||||
|
@ -45,7 +45,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.filter.CharacterEncodingFilter;
|
import org.springframework.web.filter.CharacterEncodingFilter;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.DevGuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.DevGuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.DevWebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.DevWebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
@ -59,13 +58,13 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
@RestController
|
@RestController
|
||||||
@Order(6)
|
@Order(7)
|
||||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ErrorController {
|
public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ErrorController {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(WebSecurityConfig.class);
|
private static final Logger log = LoggerFactory.getLogger(WebSecurityConfig.class);
|
||||||
|
|
||||||
@Value("${sebserver.webservice.api.admin.endpoint}")
|
// @Value("${sebserver.webservice.api.admin.endpoint}")
|
||||||
private String adminEndpoint;
|
// private String adminEndpoint;
|
||||||
@Value("${sebserver.webservice.api.redirect.unauthorized}")
|
@Value("${sebserver.webservice.api.redirect.unauthorized}")
|
||||||
private String unauthorizedRedirect;
|
private String unauthorizedRedirect;
|
||||||
|
|
||||||
|
@ -101,13 +100,16 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E
|
||||||
web
|
web
|
||||||
.ignoring()
|
.ignoring()
|
||||||
.antMatchers("/error")
|
.antMatchers("/error")
|
||||||
.antMatchers(this.adminEndpoint + API.INFO_ENDPOINT + "/**");
|
// TODO this may not be necessary, test with separated GUI and webservice server
|
||||||
|
//.antMatchers(this.adminEndpoint + API.INFO_ENDPOINT + "/**")
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/error")
|
@RequestMapping("/error")
|
||||||
public void handleError(final HttpServletResponse response) throws IOException {
|
public void handleError(final HttpServletResponse response) throws IOException {
|
||||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
|
||||||
response.sendRedirect(this.unauthorizedRedirect);
|
response.setHeader(HttpHeaders.LOCATION, this.unauthorizedRedirect);
|
||||||
|
response.flushBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -123,7 +125,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E
|
||||||
@DevGuiProfile
|
@DevGuiProfile
|
||||||
@DevWebServiceProfile
|
@DevWebServiceProfile
|
||||||
public ClientHttpRequestFactory clientHttpRequestFactory() {
|
public ClientHttpRequestFactory clientHttpRequestFactory() {
|
||||||
|
|
||||||
log.info("Initialize with insecure ClientHttpRequestFactory for development");
|
log.info("Initialize with insecure ClientHttpRequestFactory for development");
|
||||||
|
|
||||||
return new DevClientHttpRequestFactory();
|
return new DevClientHttpRequestFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
@Order(4)
|
@Order(5)
|
||||||
public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
|
public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -24,7 +24,7 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
@ -43,6 +43,7 @@ import org.springframework.security.oauth2.provider.token.UserAuthenticationConv
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.WebSecurityConfig;
|
import ch.ethz.seb.sebserver.WebSecurityConfig;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebClientDetailsService;
|
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebClientDetailsService;
|
||||||
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebserviceResourceConfiguration;
|
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebserviceResourceConfiguration;
|
||||||
|
@ -64,9 +65,8 @@ import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebserviceResourceConfigu
|
||||||
* and is by default set to "/exam-api/**" */
|
* and is by default set to "/exam-api/**" */
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
@Configuration
|
@Configuration
|
||||||
//@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@Order(5)
|
@Order(6)
|
||||||
@Import(DataSourceAutoConfiguration.class)
|
@Import(DataSourceAutoConfiguration.class)
|
||||||
public class WebServiceSecurityConfig extends WebSecurityConfigurerAdapter {
|
public class WebServiceSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@ -89,6 +89,8 @@ public class WebServiceSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
private String adminAPIEndpoint;
|
private String adminAPIEndpoint;
|
||||||
@Value("${sebserver.webservice.api.exam.endpoint}")
|
@Value("${sebserver.webservice.api.exam.endpoint}")
|
||||||
private String examAPIEndpoint;
|
private String examAPIEndpoint;
|
||||||
|
@Value("${management.endpoints.web.base-path}")
|
||||||
|
private String actuatorEndpoint;
|
||||||
@Value("${sebserver.webservice.api.redirect.unauthorized}")
|
@Value("${sebserver.webservice.api.redirect.unauthorized}")
|
||||||
private String unauthorizedRedirect;
|
private String unauthorizedRedirect;
|
||||||
|
|
||||||
|
@ -154,6 +156,16 @@ public class WebServiceSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
this.examAPIEndpoint);
|
this.examAPIEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
protected ResourceServerConfiguration sebServerActuatorResources() throws Exception {
|
||||||
|
return new ActuatorResourceServerConfiguration(
|
||||||
|
this.tokenStore,
|
||||||
|
this.webServiceClientDetails,
|
||||||
|
authenticationManagerBean(),
|
||||||
|
this.actuatorEndpoint,
|
||||||
|
this.unauthorizedRedirect);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: We need two different class types here to support Spring configuration for different
|
// NOTE: We need two different class types here to support Spring configuration for different
|
||||||
// ResourceServerConfiguration. There is a class type now for the Admin API as well as for the Exam API
|
// ResourceServerConfiguration. There is a class type now for the Admin API as well as for the Exam API
|
||||||
private static final class AdminAPIResourceServerConfiguration extends WebserviceResourceConfiguration {
|
private static final class AdminAPIResourceServerConfiguration extends WebserviceResourceConfiguration {
|
||||||
|
@ -191,6 +203,7 @@ public class WebServiceSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
tokenStore,
|
tokenStore,
|
||||||
webServiceClientDetails,
|
webServiceClientDetails,
|
||||||
authenticationManager,
|
authenticationManager,
|
||||||
|
// TODO create a proper error handling here with also documentation on SEB Binding Specification
|
||||||
(request, response, exception) -> {
|
(request, response, exception) -> {
|
||||||
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
|
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
@ -205,6 +218,36 @@ public class WebServiceSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class ActuatorResourceServerConfiguration extends WebserviceResourceConfiguration {
|
||||||
|
|
||||||
|
public ActuatorResourceServerConfiguration(
|
||||||
|
final TokenStore tokenStore,
|
||||||
|
final WebClientDetailsService webServiceClientDetails,
|
||||||
|
final AuthenticationManager authenticationManager,
|
||||||
|
final String apiEndpoint,
|
||||||
|
final String redirect) {
|
||||||
|
|
||||||
|
super(
|
||||||
|
tokenStore,
|
||||||
|
webServiceClientDetails,
|
||||||
|
authenticationManager,
|
||||||
|
new LoginRedirectOnUnauthorized(redirect),
|
||||||
|
ADMIN_API_RESOURCE_ID,
|
||||||
|
apiEndpoint,
|
||||||
|
true,
|
||||||
|
4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addConfiguration(final String apiEndpoint, final HttpSecurity http) throws Exception {
|
||||||
|
http.antMatcher(apiEndpoint + "/**")
|
||||||
|
.authorizeRequests()
|
||||||
|
.anyRequest()
|
||||||
|
.hasAuthority(UserRole.SEB_SERVER_ADMIN.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static class LoginRedirectOnUnauthorized implements AuthenticationEntryPoint {
|
private static class LoginRedirectOnUnauthorized implements AuthenticationEntryPoint {
|
||||||
|
|
||||||
private final String redirect;
|
private final String redirect;
|
||||||
|
@ -222,8 +265,9 @@ public class WebServiceSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
log.warn("Unauthorized Request: {} : Redirect to login after unauthorized request",
|
log.warn("Unauthorized Request: {} : Redirect to login after unauthorized request",
|
||||||
request.getRequestURI());
|
request.getRequestURI());
|
||||||
|
|
||||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
|
||||||
response.sendRedirect(this.redirect);
|
response.setHeader(HttpHeaders.LOCATION, this.redirect);
|
||||||
|
response.flushBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ public abstract class WebserviceResourceConfiguration extends ResourceServerConf
|
||||||
|
|
||||||
super();
|
super();
|
||||||
final ConfigurerAdapter configurerAdapter = new ConfigurerAdapter(
|
final ConfigurerAdapter configurerAdapter = new ConfigurerAdapter(
|
||||||
|
this,
|
||||||
tokenStore,
|
tokenStore,
|
||||||
webServiceClientDetails,
|
webServiceClientDetails,
|
||||||
authenticationManager,
|
authenticationManager,
|
||||||
|
@ -61,8 +62,13 @@ public abstract class WebserviceResourceConfiguration extends ResourceServerConf
|
||||||
super.setConfigurers(configurers);
|
super.setConfigurers(configurers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void addConfiguration(final String apiEndpoint, final HttpSecurity http) throws Exception {
|
||||||
|
// To override of additional configuration is needed
|
||||||
|
}
|
||||||
|
|
||||||
private static final class ConfigurerAdapter extends ResourceServerConfigurerAdapter {
|
private static final class ConfigurerAdapter extends ResourceServerConfigurerAdapter {
|
||||||
|
|
||||||
|
private final WebserviceResourceConfiguration webserviceResourceConfiguration;
|
||||||
private final TokenStore tokenStore;
|
private final TokenStore tokenStore;
|
||||||
private final WebClientDetailsService webServiceClientDetails;
|
private final WebClientDetailsService webServiceClientDetails;
|
||||||
private final AuthenticationManager authenticationManager;
|
private final AuthenticationManager authenticationManager;
|
||||||
|
@ -72,6 +78,7 @@ public abstract class WebserviceResourceConfiguration extends ResourceServerConf
|
||||||
private final boolean supportRefreshToken;
|
private final boolean supportRefreshToken;
|
||||||
|
|
||||||
public ConfigurerAdapter(
|
public ConfigurerAdapter(
|
||||||
|
final WebserviceResourceConfiguration webserviceResourceConfiguration,
|
||||||
final TokenStore tokenStore,
|
final TokenStore tokenStore,
|
||||||
final WebClientDetailsService webServiceClientDetails,
|
final WebClientDetailsService webServiceClientDetails,
|
||||||
final AuthenticationManager authenticationManager,
|
final AuthenticationManager authenticationManager,
|
||||||
|
@ -81,6 +88,7 @@ public abstract class WebserviceResourceConfiguration extends ResourceServerConf
|
||||||
final boolean supportRefreshToken) {
|
final boolean supportRefreshToken) {
|
||||||
|
|
||||||
super();
|
super();
|
||||||
|
this.webserviceResourceConfiguration = webserviceResourceConfiguration;
|
||||||
this.tokenStore = tokenStore;
|
this.tokenStore = tokenStore;
|
||||||
this.webServiceClientDetails = webServiceClientDetails;
|
this.webServiceClientDetails = webServiceClientDetails;
|
||||||
this.authenticationManager = authenticationManager;
|
this.authenticationManager = authenticationManager;
|
||||||
|
@ -121,6 +129,8 @@ public abstract class WebserviceResourceConfiguration extends ResourceServerConf
|
||||||
.headers().frameOptions().disable()
|
.headers().frameOptions().disable()
|
||||||
.and()
|
.and()
|
||||||
.csrf().disable();
|
.csrf().disable();
|
||||||
|
|
||||||
|
this.webserviceResourceConfiguration.addConfiguration(this.apiEndpoint, http);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,5 +17,7 @@ sebserver.webservice.api.exam.endpoint=/exam-api/v1
|
||||||
sebserver.webservice.api.exam.accessTokenValiditySeconds=1800
|
sebserver.webservice.api.exam.accessTokenValiditySeconds=1800
|
||||||
sebserver.webservice.api.exam.refreshTokenValiditySeconds=-1
|
sebserver.webservice.api.exam.refreshTokenValiditySeconds=-1
|
||||||
|
|
||||||
|
management.endpoints.web.base-path=/actuator
|
||||||
|
|
||||||
sebserver.webservice.api.pagination.maxPageSize=500
|
sebserver.webservice.api.pagination.maxPageSize=500
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue