If you are using Spring security in your application and if you are trying to add your application url in a frame/iframe in a view then you probably came across error “refused to display in a frame because it set ‘x-frame-options‘ to ‘deny‘” in the browser. In this guide we will discuss how to disable/customize ‘X-Frame-Options‘ response header in Spring Boot Security.
1. Root Cause
Spring Security by default includes the following Security HTTP headers. In the default HTTP security headers X-Frame-Options is set to DENY. Which means this application url can not be used in any frame/iframes. If we use url in any frame in same or external applications we see error “refused to display <url> in a frame because it set ‘x-frame-options’ to ‘deny’” in browser.
The default headers include are: Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-Content-Type-Options: nosniff Strict-Transport-Security: max-age=31536000 ; includeSubDomains X-Frame-Options: DENY X-XSS-Protection: 1; mode=block
2. how to disable/customize X-Frame-Options response header in Spring Boot Security
In Spring Boot application there are couple of ways we disable or customize X-Frame-Options in security headers. In java configuration X-Frame-Options can be changed in following ways.
- Set X-Frame-Options value as SAMEORIGIN
- Using
Content-Security-Policy
configuration
1. Set X-Frame-Options value as SAMEORIGIN
Following example demonstrates how to set http security header X-Frame-Options value as SAMEORIGIN. Which means the url you can be included in any frame/iframe within same application.
@Override protected void configure(final HttpSecurity http) throws Exception { http.headers().frameOptions().sameOrigin().and() . // more config }
2. Using Content-Security-Policy
configuration
The above configuration only allows to include application url in frames within same domain/origin. To enable including in frames in multiple domains we can setup Content-Security-Policy
with frame-ancestors.
@Override protected void configure(final HttpSecurity http) throws Exception { http.headers().frameOptions().and().contentSecurityPolicy("frame-ancestors 'self' https://javabydeveloper.com hhtps://*.javabydeveloper.com").and().and() . // more config }
You can also use HeaderWriter
implementation for the X-Frame-Options headers. http.headers().frameOptions().and().addHeaderWriter((new StaticHeadersWriter("X-FRAME-OPTIONS", "ALLOW-FROM https://javabydeveloper.com")))
. When using the ALLOW-FROM directive the actual value is determined by a AllowFromStrategy
. Note that, ALLOW-FROM is an obsolete directive that no longer works in modern browsers. Instead use Content-Security-Policy with the frame-ancestors directive like showed in above example. Refer documentation.
3. XML Old style
You can customize X-Frame-Options with the frame-options element. Following example will instruct Spring Security to use X-Frame-Options as SAMEORIGIN which allows iframes within the same domain.
<http> <!-- ... --> <headers> <frame-options policy="SAMEORIGIN" /> </headers> </http>
3. Conclusion
In this guide we discussed about the causing for the error refused to display <url> in a frame because it set ‘x-frame-options’ to ‘deny’ in Spring applications and root cause for the error in view page. We have seen couple of examples on how to disable/customize X-Frame-Options response header in Spring Boot Security
4. References
Other Related Tutorials:
- Spring @Order
- Spring @Lazy
- Spring @Autowired
- Spring Boot XML Beans
- Spring @Primary
- Spring @Import
- Spring Component Scanning
- Spring @ComponentScan Filter Types