diff --git a/config/application.tmpl b/config/application.tmpl index 069f0aa926c8711ac5db2316e9b0fa16bfe39cbe..dc4987a138f9f54b84b03e2cb18b099c24c76c2c 100644 --- a/config/application.tmpl +++ b/config/application.tmpl @@ -1,5 +1,6 @@ # Configuration template for the portal running inside a Docker container +# See http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html spring: datasource: url: {{ default .Env.DB_URL "jdbc:postgresql://172.22.0.1:5432/postgres" }} @@ -9,12 +10,17 @@ spring: jpa: hibernate: dialect: org.hibernate.dialect.PostgreSQL9Dialect + # SPRING RESOURCES HANDLING resources: - chain: - enabled: true + chain: + enabled: true # TODO: why is that enabled? Do we serve any resources from the backend? +# SECURITY security: - enabled: false + enabled: false # TODO: why Spring security is disabled? It supports OAuth2 out of the box... + +authentication: + enabled: {{ default .Env.AUTHENTICATION "1" }} hbp: client: @@ -28,11 +34,18 @@ hbp: resource: userInfoUri: {{ default .Env.USER_INFO_URI "https://services.humanbrainproject.eu/oidc/userinfo" }} +# WEB FRONTEND +frontend: + loginUrl: {{ default .Env.LOGIN_URL "http://frontend/services/login/hbp" }} + redirectAfterLogoutUrl: {{ default .Env.AFTER_LOGOUT_URL (default .Env.LOGIN_URI "http://frontend/services/login/hbp") }} + redirectAfterLoginUrl: {{ default .Env.AFTER_LOGIN_URL "http://frontend/home" }} + logging: level: logging.level.org.springframework.web = {{ default .Env.LOGGING_LEVEL_WEB "WARN" }} logging.level.org.hibernate = {{ default .Env.LOGGING_LEVEL_HIBERNATE "WARN" }} +# EMBEDDED SERVER CONFIGURATION server: contextPath: {{ default .Env.CONTEXT_PATH "/services" }} port: 8080 @@ -40,15 +53,16 @@ server: session: timeout: {{ default .Env.SESSION_TIMEOUT "2592000" }} +# ENDPOINTS +endpoints + enabled: true + health: + enabled: true + endoint: /health + sentitive: false + workflow: experimentUrl: {{ default .Env.WOKEN_URL "http://172.22.0.1:8087" }}/experiment listMethodsUrl: {{ default .Env.WOKEN_URL "http://172.22.0.1:8087" }}/list-methods miningMipUrl: {{ default .Env.WOKEN_URL "http://172.22.0.1:8087" }}/mining" miningExaremeUrl: {{ default .Env.EXAREME_URL "http://hbps2.chuv.ch:9090" }}/mining/query - -frontend: - redirect: - url: {{ default .Env.FRONTEND_REDIRECT_URL "http://frontend/home" }} - -authentication: - enabled: {{ default .Env.AUTHENTICATION "1" }} diff --git a/src/docker/run/README.md b/src/docker/run/README.md index b1f0a90eef230aa70494f3905b3548cadb283d98..564ebd0a69a63aa654e1b51c4495bc389c04e916 100644 --- a/src/docker/run/README.md +++ b/src/docker/run/README.md @@ -12,16 +12,18 @@ Environment variables: * DB_URL: JDBC URL to connect to the database, for example "jdbc:postgresql://db:5432/portal" * DB_USER: User to use when connecting to the database * DB_PASSWORD: Password to use when connecting to the database +* CONTEXT_PATH: context path appended to all services running in this container. Default to "/services" * AUTHENTICATION: 0 to disable authentication or 1 to enable authentication. * CLIENT_ID: required when authentication is turned on, client ID for the [OpenID server of HBP](https://services.humanbrainproject.eu/oidc/) * CLIENT_SECRET: required when authentication is turned on, client secret for the [OpenID server of HBP](https://services.humanbrainproject.eu/oidc/) * TOKEN_URI: default to "https://services.humanbrainproject.eu/oidc/token" * AUTH_URI: default to "https://services.humanbrainproject.eu/oidc/authorize" * USER_INFO_URI: default to "https://services.humanbrainproject.eu/oidc/userinfo" +* FRONTEND_LOGIN_URL: URL to redirect to when login is required. Default to "http://frontend/services/login/hbp" +* FRONTEND_AFTER_LOGIN_URL: URL to redirect after login. Default to "http://frontend/home" +* FRONTEND_AFTER_LOGOUT_URL: URL to redirect to after logout. Default to "http://frontend/services/login/hbp" +* WOKEN_URL: URL to woken machine learning server. +* EXAREME_URL: URL to Exareme server. * LOGGING_LEVEL_WEB: log level for the web layer of the application. Default to "DEBUG" * LOGGING_LEVEL_HIBERNATE: log level for the Hibernate layer of the application. Default to "DEBUG" -* CONTEXT_PATH: context path appended to all services running in this container. Default to "/services" * SESSION_TIMEOUT: Timeout in milliseconds for session expiration. Default to 2592000 -* WOKEN_URL: URL to woken machine learning server. -* EXAREME_URL: URL to Exareme server. -* FRONTEND_REDIRECT_URL: URL to to redirect after login. Default to "http://frontend/home" diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java index c0f4a293322f31f86aeb22c524f32fd0cb42819e..600a3da5780cb8d5633e038ea8620b874ad29245 100644 --- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java +++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java @@ -57,9 +57,8 @@ import java.net.URLEncoder; import java.security.Principal; /** - * Created by mirco on 11.07.16. + * Configuration for security. */ - @Configuration @EnableOAuth2Client @RestController @@ -68,39 +67,51 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { private static final Logger LOGGER = Logger.getLogger(ArticlesApi.class); @Autowired - OAuth2ClientContext oauth2ClientContext; + private OAuth2ClientContext oauth2ClientContext; @Autowired - UserRepository userRepository; + private UserRepository userRepository; - @Value("#{'${hbp.client.pre-established-redirect-uri:/login/hbp}'}") - String loginUrl; + /** + * Enable authentication (1) or disable it (0). Default is 1 + */ + @Value("#{'${authentication.enabled:1}'}") + private boolean authentication; - @Value("#{'${hbp.client.logout-uri:/logout}'}") - String logoutUrl; + /** + * Absolute URL to redirect to when login is required + */ + @Value("#{'${frontend.loginUrl:/login/hbp}'}") + private String loginUrl; - @Value("#{'${frontend.redirect.url:http://frontend/home}'}") - String frontendRedirect; + /** + * Absolute URL to redirect to after successful login + */ + @Value("#{'${frontend.redirectAfterLoginUrl:http://frontend/home}'}") + private String frontendRedirectAfterLogin; - @Value("#{'${authentication.enabled:1}'}") - boolean authentication; + /** + * Absolute URL to redirect to after logout has occurred + */ + @Value("#{'${frontend.redirectAfterLogoutUrl:/login/hbp}'}") + private String redirectAfterLogoutUrl; @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class); - if(authentication) { + if (authentication) { http.antMatcher("/**") .authorizeRequests() .antMatchers( - "/", "/health/**", "/info/**", "/metrics/**", "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs" + "/", "/login/**", "/health/**", "/info/**", "/metrics/**", "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs" ).permitAll() .anyRequest().authenticated() .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl)) - .and().logout().logoutSuccessUrl(loginUrl).permitAll() - .and().logout().logoutUrl(logoutUrl).permitAll() - .and().csrf().ignoringAntMatchers(logoutUrl).csrfTokenRepository(csrfTokenRepository()) + .and().logout().logoutSuccessUrl(redirectAfterLogoutUrl) + .and().logout().permitAll() + .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository()) .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class) .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class); } @@ -115,7 +126,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { private Filter ssoFilter() { OAuth2ClientAuthenticationProcessingFilter hbpFilter = new OAuth2ClientAuthenticationProcessingFilter(loginUrl); OAuth2RestTemplate hbpTemplate = new OAuth2RestTemplate(hbp(), oauth2ClientContext); - hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirect)); + hbpFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler(frontendRedirectAfterLogin)); hbpFilter.setRestTemplate(hbpTemplate); hbpFilter.setTokenServices(new UserInfoTokenServices(hbpResource().getUserInfoUri(), hbp().getClientId())); return hbpFilter; @@ -168,12 +179,14 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { return repository; } - public String getUserInfos() { + private String getUserInfos() { OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication(); Authentication userAuthentication = oAuth2Authentication.getUserAuthentication(); return userAuthentication.getDetails().toString(); } + private transient User user; + /** * returns the user for the current session. * <p> @@ -184,23 +197,22 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { * - log in using the front end * - check you have no 500 error in the network logs. * - * @return + * @return the user for the current session */ public synchronized User getUser() { - User user; - if(!authentication) - { - user = new User(); - user.setUsername("TestUser"); - } - else { - user = new User(getUserInfos()); - User foundUser = userRepository.findOne(user.getUsername()); - if (foundUser != null) { - user.setAgreeNDA(foundUser.getAgreeNDA()); + if (user == null) { + if (!authentication) { + user = new User(); + user.setUsername("TestUser"); + } else { + user = new User(getUserInfos()); + User foundUser = userRepository.findOne(user.getUsername()); + if (foundUser != null) { + user.setAgreeNDA(foundUser.getAgreeNDA()); + } } + userRepository.save(user); } - userRepository.save(user); return user; } @@ -221,7 +233,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { } @RequestMapping(path = "/user", method = RequestMethod.POST) - public ResponseEntity<Void> postUser(@ApiParam(value = "Has the user agreed on the NDA") @RequestParam(value = "agreeNDA", required = true) Boolean agreeNDA) { + public ResponseEntity<Void> postUser(@ApiParam(value = "Has the user agreed on the NDA") @RequestParam(value = "agreeNDA") Boolean agreeNDA) { User user = getUser(); if (user != null) { user.setAgreeNDA(agreeNDA);