diff --git a/Dockerfile b/Dockerfile index bd00e6f3f08ed34c67813b750ed4f99a18352dcf..bf47525ce60f20b1907521a1df4785086ed74762 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,11 +31,11 @@ COPY --from=java-build-env /project/target/portal-backend.jar /usr/share/jars/ ENTRYPOINT ["/run.sh"] -# 8080: Web service API, health checks on http://host:8080/$CONTEXT_PATH/health +# 8080: Web service API, health checks on http://host:8080$CONTEXT_PATH/health # 4089: Akka cluster EXPOSE 4089 8080 -HEALTHCHECK --start-period=60s CMD curl -v --silent http://localhost:8080/$CONTEXT_PATH/health 2>&1 | grep UP +HEALTHCHECK --start-period=60s CMD curl -v --silent http://localhost:8080$CONTEXT_PATH/health 2>&1 | grep UP LABEL org.label-schema.build-date=$BUILD_DATE \ org.label-schema.name="hbpmip/portal-backend" \ diff --git a/docker/config/application.tmpl b/docker/config/application.tmpl index fcdc4ec92f27f0876f4bbd9d9d24c4f157fc1e4e..d37bc35132a6ed2d2df285fb8a39342515803072 100644 --- a/docker/config/application.tmpl +++ b/docker/config/application.tmpl @@ -65,6 +65,7 @@ logging: org: springframework: web: {{ default .Env.LOGGING_LEVEL_WEB "WARN" }} + web.servlet.handler.BeanNameUrlHandlerMapping: WARN hibernate: {{ default .Env.LOGGING_LEVEL_HIBERNATE "WARN" }} eu: hbp: {{ default .Env.LOGGING_LEVEL_MIP "INFO" }} diff --git a/pom.xml b/pom.xml index e6571d6e2633bad8c6ad69d64753611c8df216f7..ab304cbca9bcb04c47901e56bfddc6666806be2f 100644 --- a/pom.xml +++ b/pom.xml @@ -99,6 +99,14 @@ <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-oauth2-client</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-oauth2-jose</artifactId> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> diff --git a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java index 51615b207efb4c695ec4c00beaacfc25273cf012..28d482ddfbcf4fe0bc4ae2bf1e141681a6b56138 100644 --- a/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java +++ b/src/main/java/eu/hbp/mip/configuration/SecurityConfiguration.java @@ -2,7 +2,6 @@ package eu.hbp.mip.configuration; import eu.hbp.mip.model.UserInfo; import eu.hbp.mip.utils.CORSFilter; -import eu.hbp.mip.utils.CustomLoginUrlAuthenticationEntryPoint; import eu.hbp.mip.utils.HTTPUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,6 +14,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.core.Authentication; import org.springframework.security.oauth2.client.OAuth2ClientContext; @@ -25,6 +25,7 @@ import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResour import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; import org.springframework.security.web.access.channel.ChannelProcessingFilter; +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutHandler; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; @@ -32,6 +33,11 @@ import org.springframework.security.web.csrf.CsrfFilter; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.security.web.csrf.CsrfTokenRepository; import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; +import org.springframework.security.web.firewall.FirewalledRequest; +import org.springframework.security.web.firewall.HttpFirewall; +import org.springframework.security.web.firewall.RequestRejectedException; +import org.springframework.security.web.firewall.StrictHttpFirewall; +import org.springframework.web.filter.CommonsRequestLoggingFilter; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.WebUtils; @@ -88,6 +94,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Value("#{'${hbp.resource.revokeTokenUri:https://services.humanbrainproject.eu/oidc/revoke}'}") private String revokeTokenURI; + @Override + public void configure(WebSecurity web) throws Exception { + super.configure(web); + web.httpFirewall(allowUrlEncodedSlashHttpFirewall()); + } + @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off @@ -100,11 +112,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { "/", "/login/**", "/health/**", "/info/**", "/metrics/**", "/trace/**", "/frontend/**", "/webjars/**", "/v2/api-docs", "/swagger-ui.html", "/swagger-resources/**" ).permitAll() .anyRequest().authenticated() - .and().exceptionHandling().authenticationEntryPoint(new CustomLoginUrlAuthenticationEntryPoint(loginUrl)) + .and().exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint(loginUrl)) .and().logout().addLogoutHandler(new CustomLogoutHandler()).logoutSuccessUrl(redirectAfterLogoutUrl) .and().logout().permitAll() .and().csrf().ignoringAntMatchers("/logout").csrfTokenRepository(csrfTokenRepository()) .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class) + .addFilterBefore(requestLoggingFilter(), BasicAuthenticationFilter.class) .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class); } else { @@ -132,6 +145,29 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { return registration; } + @Bean + public CommonsRequestLoggingFilter requestLoggingFilter() { + CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter(); + loggingFilter.setIncludeClientInfo(true); + loggingFilter.setIncludeHeaders(true); + loggingFilter.setIncludeQueryString(true); + loggingFilter.setIncludePayload(true); + return loggingFilter; + } + + @Bean + public HttpFirewall allowUrlEncodedSlashHttpFirewall() { + StrictHttpFirewall firewall = new StrictHttpFirewall() { + @Override + public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException { + System.out.println(request.getRequestURI() + " " + request.getContextPath()); + return super.getFirewalledRequest(request); + } + }; + firewall.setAllowUrlEncodedSlash(true); + return firewall; + } + @Bean(name="hbp") @ConfigurationProperties("hbp.client") public OAuth2ProtectedResourceDetails hbp() { diff --git a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java index eb84126ff753b3b458995030ee8faf429ae5e5e9..a6ae893f9df932db208fc5680e44df012dbd4d0c 100644 --- a/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java +++ b/src/main/java/eu/hbp/mip/configuration/WebConfiguration.java @@ -24,12 +24,12 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; public class WebConfiguration { @Bean - public UiConfiguration uiConfig() { + public UiConfiguration swaggerUiConfig() { return UiConfiguration.DEFAULT; } @Bean - public Docket documentation() { + public Docket swaggerDocumentation() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("eu.hbp.mip.controllers")) @@ -46,4 +46,5 @@ public class WebConfiguration { .contact(new Contact("Mirco Nasuti", "https://www.unil.ch/lren/en/home.html", "mirco.nasuti@chuv.ch")) .build(); } + } diff --git a/src/main/java/eu/hbp/mip/utils/CustomLoginUrlAuthenticationEntryPoint.java b/src/main/java/eu/hbp/mip/utils/CustomLoginUrlAuthenticationEntryPoint.java deleted file mode 100644 index 45870c7778280ff60c8ccca2908105ee677a6f7a..0000000000000000000000000000000000000000 --- a/src/main/java/eu/hbp/mip/utils/CustomLoginUrlAuthenticationEntryPoint.java +++ /dev/null @@ -1,21 +0,0 @@ -package eu.hbp.mip.utils; - -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -public class CustomLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint { - - public CustomLoginUrlAuthenticationEntryPoint(String url) { - super(url); - } - - @Override - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } -} diff --git a/src/main/java/eu/hbp/mip/utils/HTTPUtil.java b/src/main/java/eu/hbp/mip/utils/HTTPUtil.java index c641826e8e2e8bddb7e544cc60fcebdd8fd1c600..37d3af8d830e87d7e655ba096fb496fab6eb29a5 100644 --- a/src/main/java/eu/hbp/mip/utils/HTTPUtil.java +++ b/src/main/java/eu/hbp/mip/utils/HTTPUtil.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.charset.StandardCharsets; /** * Created by mirco on 20.06.16. @@ -26,7 +27,7 @@ public class HTTPUtil { return sendHTTP(url, query, resp, "POST"); } - public static int sendHTTP(String url, String query, StringBuilder resp, String httpVerb) throws IOException { + private static int sendHTTP(String url, String query, StringBuilder resp, String httpVerb) throws IOException { URL obj = new URL(url); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); @@ -40,7 +41,7 @@ public class HTTPUtil { con.setDoOutput(true); DataOutputStream wr = new DataOutputStream(con.getOutputStream()); - wr.write(query.getBytes("UTF8")); + wr.write(query.getBytes(StandardCharsets.UTF_8)); wr.flush(); wr.close(); }