Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 48127fa2 authored by Joze RIHTARSIC's avatar Joze RIHTARSIC
Browse files

Pull request #178: Feature/EDELIVERY-6312 hsts headers

Merge in EDELIVERY/smp from feature/EDELIVERY-6312-hsts-headers to feature/EDELIVERY-8880-use-eu-login-for-smp-console-implementation-part-2

* commit '0478917ebcaa3747a9a3150e32dbc8bf127cfec2':
  remove parent pom
  HSTS small fix
  update favicon ico
  Enable HSTS and add property for max age
parents 34101693 a29a6ef3
No related branches found
No related tags found
No related merge requests found
Showing
with 595 additions and 887 deletions
......@@ -15,4 +15,5 @@ Domibus 4.2
smp.sso.cas.token.validation.urlpath: The CAS URL path for login. Complete URL is composed from parameters: ${smp.sso.cas.url}/${smp.sso.cas.urlpath.token.validation}.
smp.sso.cas.token.validation.params: The CAS token validation key:value properties separated with '|'.Ex: 'acceptStrengths:BASIC,CLIENT_CERT|assuranceLevel:TOP'
smp.sso.cas.token.validation.groups: The '|' separated CAS groups user must belong to.
smp.http.httpStrictTransportSecurity.maxAge: How long(in seconds) HSTS should last in the browser's cache(default one year)
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
<!--
~ Copyright 2017 European Commission | CEF eDelivery
~
~ Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence");
~ You may not use this work except in compliance with the Licence.
~
~ You may obtain a copy of the Licence attached in file: LICENCE-EUPL-v1.2.pdf
~
~ Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the Licence for the specific language governing permissions and limitations under the Licence.
-->
<settings>
<proxies>
<proxy>
<id>httpProxy</id>
<active>true</active>
<protocol>http</protocol>
<host>158.169.9.13</host>
<port>8012</port>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</proxy>
<proxy>
<id>httpsProxy</id>
<active>true</active>
<protocol>https</protocol>
<host>158.169.9.13</host>
<port>8012</port>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</proxy>
</proxies>
<mirrors>
<mirror>
<id>internal-repository</id>
<name>Maven Repository Manager running on repo.mycompany.com</name>
<url>https://joinup.ec.europa.eu/nexus/content/groups/public</url>
<mirrorOf>open-saml</mirrorOf>
</mirror>
</mirrors>
<servers>
<server>
<id>edelivery-snapshots</id>
<username>gutowpa</username>
<password>{2y/aQkOSNGYHhuusKhaDwLP/lm5YFzlJwyjUWXFDh74=}</password>
</server>
<server>
<id>edelivery-releases</id>
<username>gutowpa</username>
<password>{2y/aQkOSNGYHhuusKhaDwLP/lm5YFzlJwyjUWXFDh74=}</password>
</server>
<server>
<id>cefdigital-snapshots</id>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</server>
<server>
<id>cefdigital-releases</id>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</server>
<server>
<id>cefdigital-thirdparty</id>
<username>gutowpa</username>
<password>{2y/aQkOSNGYHhuusKhaDwLP/lm5YFzlJwyjUWXFDh74=}</password>
</server>
<server>
<id>webgate-digit</id>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</server>
<server>
<id>webgate-digit-third-party</id>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</server>
<server>
<id>webgate-digit-soapui</id>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</server>
<server>
<id>joinup-releases</id>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</server>
<server>
<id>joinup-snapshots</id>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</server>
<server>
<id>joinup-3rdparty</id>
<username>j50b107</username>
<password>{AP1hP8sE97kHFzAatQGzaaiQPGFrOMDFUZFfG3xTxOs=}</password>
</server>
</servers>
</settings>
\ No newline at end of file
......@@ -12,6 +12,7 @@ public enum SMPPropertyEnum {
OUTPUT_CONTEXT_PATH ("contextPath.output","true","This property controls pattern of URLs produced by SMP in GET ServiceGroup responses." , true, false,true, SMPPropertyTypeEnum.BOOLEAN),
HTTP_FORWARDED_HEADERS_ENABLED ("smp.http.forwarded.headers.enabled","false","Use (value true) or remove (value false) forwarded headers! There are security considerations for forwarded headers since an application cannot know if the headers were added by a proxy, as intended, or by a malicious client." , false, false,false, SMPPropertyTypeEnum.BOOLEAN),
HTTP_HSTS_MAX_AGE("smp.http.httpStrictTransportSecurity.maxAge","31536000","How long(in seconds) HSTS should last in the browser's cache(default one year)", false, false,true, SMPPropertyTypeEnum.INTEGER),
HTTP_PROXY_HOST("smp.proxy.host", "", "The http proxy host", false,false,false, SMPPropertyTypeEnum.STRING),
HTTP_NO_PROXY_HOSTS("smp.noproxy.hosts", "localhost|127.0.0.1", "list of nor proxy hosts. Ex.: localhost|127.0.0.1", false,false,false, SMPPropertyTypeEnum.STRING),
......@@ -60,7 +61,7 @@ public enum SMPPropertyEnum {
UI_COOKIE_SESSION_SECURE("smp.ui.session.secure","false","Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistant to man-in-the-middle attacks.", false, false,false, SMPPropertyTypeEnum.BOOLEAN),
UI_COOKIE_SESSION_MAX_AGE("smp.ui.session.max-age","","Number of seconds until the cookie expires. A zero or negative number will expire the cookie immediately. Empty value will not set parameter", false, false,false, SMPPropertyTypeEnum.INTEGER),
UI_COOKIE_SESSION_SITE("smp.ui.session.strict","Lax","Controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks. Possible values are: Strict, None, Lax. (Cookies with SameSite=None require a secure context/HTTPS)!!)", false, false,false, SMPPropertyTypeEnum.STRING),
UI_COOKIE_SESSION_PATH("smp.ui.session.path","","A path that must exist in the requested URL, or the browser won't send the Cookie header. Null/Empty value sets the authentication requests context by default. The forward slash (/) character is interpreted as a directory separator, and subdirectories will be matched as well: for Path=/docs, /docs, /docs/Web/, and /docs/Web/HTTP will all match", false, false,false, SMPPropertyTypeEnum.STRING),
UI_COOKIE_SESSION_PATH("smp.ui.session.path","","A path that must exist in the requested URL, or the browser won't send the Cookie header. Null/Empty value sets the authentication requests context by default. The forward slash (/) character is interpreted as a directory separator, and subdirectories will be matched as well: for Path=/docs, /docs, /docs/Web/, and /docs/Web/HTTP will all match", false, false,false, SMPPropertyTypeEnum.STRING),
UI_COOKIE_SESSION_IDLE_TIMEOUT_ADMIN("smp.ui.session.idle_timeout.admin","300","Specifies the time, in seconds, between client requests before the SMP will invalidate session for ADMIN users (System)!", false, false,false, SMPPropertyTypeEnum.INTEGER),
UI_COOKIE_SESSION_IDLE_TIMEOUT_USER("smp.ui.session.idle_timeout.user","1800","Specifies the time, in seconds, between client requests before the SMP will invalidate session for users (Service group, SMP Admin)", false, false,false, SMPPropertyTypeEnum.INTEGER),
......
......@@ -69,6 +69,10 @@ public class ConfigurationService {
return configurationDAO.getCachedProperty(PARTC_SCH_REGEXP_MSG);
}
public Integer getHttpHeaderHstsMaxAge() {
return (Integer) configurationDAO.getCachedPropertyValue(HTTP_HSTS_MAX_AGE);
}
public String getHttpProxyHost() {
return configurationDAO.getCachedProperty(HTTP_PROXY_HOST);
}
......@@ -220,6 +224,7 @@ public class ConfigurationService {
public Map<String, String> getCasTokenValidationParams() {
return (Map<String, String>) configurationDAO.getCachedPropertyValue(SSO_CAS_TOKEN_VALIDATION_PARAMS);
}
public List<String> getCasURLTokenValidationGroups() {
return (List<String>) configurationDAO.getCachedPropertyValue(SSO_CAS_TOKEN_VALIDATION_GROUPS);
}
......
......@@ -52,7 +52,7 @@ public class SmpWebAppConfig implements WebMvcConfigurer {
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.setOrder(HIGHEST_PRECEDENCE)
.addResourceHandler("/index.html", "/favicon-16x16.png").addResourceLocations("/static_resources/");
.addResourceHandler("/index.html", "/favicon.png", "/favicon.ico").addResourceLocations("/html/");
registry.setOrder(HIGHEST_PRECEDENCE - 2)
.addResourceHandler("/ui/rest/").addResourceLocations("/"); // ui rest resources
......
......@@ -50,6 +50,7 @@ import org.springframework.security.web.firewall.DefaultHttpFirewall;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
......@@ -128,7 +129,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
ExceptionHandlingConfigurer<HttpSecurity> exceptionHandlingConfigurer = httpSecurity.exceptionHandling();
if (configurationService.isCasEnabled()) {
LOG.info("REGISTER casAuthenticationEntryPoint: [{}]", casAuthenticationEntryPoint);
LOG.debug("The CAS authentication is enabled. Set casAuthenticationEntryPoint!");
exceptionHandlingConfigurer = exceptionHandlingConfigurer.defaultAuthenticationEntryPointFor(casAuthenticationEntryPoint, new AntPathRequestMatcher(SMP_SECURITY_PATH_CAS_AUTHENTICATE));
}
exceptionHandlingConfigurer.authenticationEntryPoint(new SpringSecurityExceptionHandler());
......@@ -142,8 +143,30 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
.and();
if (configurationService.isCasEnabled()) {
LOG.debug("The CAS authentication is enabled. Add CAS filter!");
httpSecurity = httpSecurity.addFilter(casAuthenticationFilter);
}
// set HstsMAxAge
Integer maxAge = configurationService.getHttpHeaderHstsMaxAge();
if (maxAge == null || maxAge < 0){
LOG.info("The httpStrictTransportSecurity (HSTS) policy is set for HTTPS/1Y!" );
httpSecurity = httpSecurity.headers()
.httpStrictTransportSecurity()
.includeSubDomains(true)
.preload(false)
.maxAgeInSeconds(31536000).and().and();
}else if ( maxAge == 0){
LOG.warn("The httpStrictTransportSecurity (HSTS) policy is disabled!" );
httpSecurity = httpSecurity.headers().httpStrictTransportSecurity().disable().and();
} else {
LOG.info("The httpStrictTransportSecurity (HSTS) policy is set to [{}] for http and https!",maxAge );
httpSecurity = httpSecurity.headers()
.httpStrictTransportSecurity()
.includeSubDomains(true)
.preload(false)
.maxAgeInSeconds(maxAge)
.requestMatcher(AnyRequestMatcher.INSTANCE).and().and();
}
httpSecurity.addFilter(blueCoatAuthenticationFilter)
.addFilter(x509AuthenticationFilter)
......
......@@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
......@@ -48,20 +49,26 @@ public class RootController {
return new ModelAndView("redirect:/index.html", model);
}
@GetMapping( produces = {MediaType.TEXT_HTML_VALUE, MediaType.IMAGE_PNG_VALUE},
value={ "/index.html", "/favicon-16x16.png"})
@GetMapping( produces = {MediaType.TEXT_HTML_VALUE,
MediaType.IMAGE_PNG_VALUE,
"image/ico","image/x-ico"
},
value={ "/index.html","/favicon.png","/favicon.ico"})
@Order(HIGHEST_PRECEDENCE)
public byte[] getServiceGroup(HttpServletRequest httpReq) throws IOException {
public byte[] getServiceGroup(HttpServletRequest httpReq, HttpServletResponse httpRes) throws IOException {
String host = httpReq.getRemoteHost();
LOG.businessInfo(SMPMessageCode.BUS_HTTP_GET_END_STATIC_CONTENT,host,httpReq.getPathInfo());
String value = httpReq.getServletPath();
if(value!=null && value.endsWith("favicon-16x16.png")){
return IOUtils.readBytesFromStream(RootController.class.getResourceAsStream("/html/favicon-16x16.png"));
}else {
String value = httpReq.getPathInfo();
if(value!=null && value.endsWith("favicon.png")){
httpRes.setContentType("image/x-ico");
return IOUtils.readBytesFromStream(RootController.class.getResourceAsStream("/html/favicon.png"));
}else if(value!=null && value.endsWith("favicon.ico")){
httpRes.setContentType(MediaType.IMAGE_PNG_VALUE);
return IOUtils.readBytesFromStream(RootController.class.getResourceAsStream("/html/favicon.ico"));
} else {
return IOUtils.readBytesFromStream(RootController.class.getResourceAsStream("/html/index.html"));
}
}
/**
* redirect angular pages to index.html
* solve the 404 error on refresh
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
<!--
~ Copyright 2017 European Commission | CEF eDelivery
~ Copyright 2017-2022 European Commission | CEF eDelivery
~
~ Licensed under the EUPL, Version 1.2 or – as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence");
~ You may not use this work except in compliance with the Licence.
......@@ -14,9 +14,8 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>SMP</title>
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="icon" type="image/x-ico" href="favicon.ico">
<style type="text/css">
body { font-family: Arial, Helvetica, sans-serif; }
a, a:link, a:visited, a:hover, a:active { color: blue; }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment