I'm trying to enable HSTS in my Spring Boot application. I've added the following to my WebSecurityConfig (based on Enable HTTP Strict Transport Security (HSTS) with spring boot application):
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
protected void configure(HttpSecurity http) throws Exception
{
// Other http configurations, e.g. authorizeRequests and CSRF
// ...
http.headers().httpStrictTransportSecurity()
.maxAgeInSeconds(Duration.ofDays(365L).getSeconds())
.includeSubDomains(true);
}
}
I do get the strict-transport-security header when in HTTPS requests, but the max-age is always 0:
strict-transport-security: max-age=0; includeSubDomains
I'm getting the exact same header if I don't add the Spring configuration, so it looks my configuration is not being picked up. It appears to be specific to the HSTS configuration, because the other configurations, e.g. http.authorizeRequests(), are working. That seems to indicate that the HSTS configuration is somehow being overwritten, especially when considering that Spring's default max-age is one year. However, I've been able to find any other HSTS-related configuration in our codebase.
I also tried setting a breakpoint in o.springframework.s.c.a.w.c.HeadersConfigurer.HstsConfig#maxAgeInSeconds to check whether it's being called more than once. My call from configure was the only invocation.
Does anyone know why my HSTS configuration is not used? Or do you have any other ideas on how to debug this?
Turns out that this was caused by a Cloudflare configuration that rewrote the header and set the max-age to 0.
It was also easier to update the Cloudflare configuration than to update the configuration in every micro-service.
Related
I am trying to implement Spring basic auth into the app. I added the folowing lines to application.properties:
#Security
security:
user:
name: admin
password: admin
So the Spring will create a web security config bean by itself. But I ran some tests and everything works as expected for any method besides POST as it throws 403 status. I browsed the web and discovered that it happens due to csrf protection and I disabled it, creating additional web security config class:
#EnableWebSecurity
public class WebSecurityConfig {
#Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
return http.build();
}
}
However, it completely disables the authentication. The user does not need a password and a login to use the resources.
My question is, how do I configure the authentication in a way POST method will not throw 403? Do I need to write a full web security config and delete those 4 lines from application.properties or there is an alternative way? Thanks in advance.
I could reload application on edit with RemoteSpringApplication until I added spring security to my app,
with
#EnableWebSecurity
public class WebAuthConfig extends WebSecurityConfigurerAdapter { ..
etc
event though I added:
// TODO: this disable all security checks httpSecurity.httpBasic().disable().authorizeRequests().anyRequest().permitAll();
so all my rest calls still works without any auth,
as soon as I change the code and running RemoteSpringApplication detects the change it fails with:
Exception in thread "File Watcher" java.lang.IllegalStateException: Unexpected 403 response uploading class files
How to prevent it?
Thx
Add:
.authorizeRequests()
.antMatchers("/.~~spring-boot!~/**")
.permitAll()
.and()
to your Spring Security config near the top of your http method chain in the configure(HttpSecurity http) method and it'll disable Spring Security on the Spring Boot DevTools URL.
If you want to change this URL you can override it by changing the spring.devtools.remote.context-path property in your application.properties.
Make sure you're not running devtools in production of course!!
I have migrated a Spring Boot web application from 1.5.10 to 2.0.0, which is deployed with Heroku and runs over several domains. For the main domain, that was the first one to be set, everything is working smoothly but for the rest any of the static resources; like Javascript, CSS, images and icons (Webjars) are not accessible.
maindomain.com/js/example.js works fine and can be directly accessed with the browser. secondarydomain.com/js/example.js can't be accessed by the browser and running the app arises this error, I guess because instead of the .js file is returning some text message:
Refused to execute script from '' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled
The static resources are located at:
/resources/static/css
/resources/static/js
/resources/static/images
I have set the Spring security configuration with an extension of WebSecurityConfigurerAdapter, where I have withdrawn the annotation #EnableWebSecurity and I have added this code, with the intention to make sure that those resources are accessible, without success:
http
.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
There is a HandleInterceptor, which deals with the directories accessible by each secondary domain. The main one, has access all over the application.
In this other question, with a different approach to the same problem, there is an extract of the HandleInterceptor.
Spring Boot 2.0.0 & static resources with different domains for the same app
Spring Security with boot is on the classpath, the auto-configuration secures all endpoints by default.
However, when it comes to complex applications, we need different security policies per endpoints. We also need to configure which endpoints should be secured, what type of users should be able to access the endpoints, and which endpoints should be public.
WebSecurity allow we to configure adding RequestMatcher instances that Spring Security should ignore.
HttpSecurity allow we can configure the endpoints that should be secured and the endpoint that should be public
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/image/**"").permitAll()
}
}
Hope it help.
Trying to apply multiple http configuration as described in the documentation multiple-httpsecurity
Using Spring-4.1.6.RELEASE and Spring-Security-4.0.1.RELEASE (also tried 3.2.7.RELEASE)
As a result I'm getting only the basic auth applied against the /api/** pattern the formLogin is not working.
In the filterChain object during debug we can see that the UsernamePasswordAuthenticationFilter is missing.
On the other hand when tried to apply the #Order(1) annotation to the FormLoginWebSecurityConfigurerAdapter instead to the ApiWebSecurityConfigurationAdapter, got only the formLogin authentication applied. In the filterChain object during debug we can see that the BasicAuthenticationFilter is missing.
Feel free to use the source code of the project to reproduce the issue:
https://github.com/kmarabet/SpringSecurityMultiHttpSample
I am attempting to set the X-Frame-Options to DENY for all management endpoints, particularly the /error endpoint. I have the following in my application.properties of my Spring Boot application.
security.headers.frame=true
management.security.enabled=true
management.port=8001
When I go to http://localhost:8001/error I do not have the X-Frame-Options header, however the http://localhost:8001/trace endpoint does have the header. How do I configure my application.properties or what do I need to override to get that response header for the error endpoint?
Going through the current Spring Boot source (1.1.7.RELEASE), I don't see anyway that you can do what you want without totally doing away with the Security auto-configuration.
That is because in order for an endpoint to be eligible for the customized HTTP Headers (like X-Frame-Options) it needs to be a bean in the parent context (the one that is associated with the application on the normal port) that implements MvcEndpoint. Such beans are HealthMvcEndpoint, JolokiaMvcEndpoint etc.
My statement adove can be viewed in code at ManagementSecurityAutoConfiguration in the ManagementWebSecurityConfigurerAdapter.configure method (endpointHandlerMapping is created from the MvcEndpoint implementation beans).
The error page for the management app, is ManagementErrorEndpoint that is created in errorEndpoint of EndpointWebMvcChildContextConfiguration which is triggered when the child context is created (due the inclusion of the management app), which is too late to be included in the endpoints that supported for HTTP Headers customization
The /error endpoint is not an Actuator Endpoint and it's not secured by default (lots of errors can happen when a user is not authenticated). You could maybe make it available to anonymous users, but my guess is not even that would prevent some nasty infinite loops, where there is a mistake in the security configuration. I'm sure there's another way to add the header without Spring Security?