| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149 | [[servlet-headers]]= Security HTTP Response HeadersYou can use xref:features/exploits/headers.adoc#headers[Security HTTP Response Headers] to increase the security of web applications.This section is dedicated to servlet-based support for Security HTTP Response Headers.[[servlet-headers-default]]== Default Security HeadersSpring Security provides a xref:features/exploits/headers.adoc#headers-default[default set of Security HTTP Response Headers] to provide secure defaults.While each of these headers are considered best practice, it should be noted that not all clients use the headers, so additional testing is encouraged.You can customize specific headers.For example, assume that you want the defaults but you wish to specify `SAMEORIGIN` for <<servlet-headers-frame-options,X-Frame-Options>>.You can do so with the following configuration:.Customize Default Security Headers====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extends		WebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) {		http			// ...			.headers(headers -> headers				.frameOptions(frameOptions -> frameOptions					.sameOrigin()				)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<frame-options policy="SAMEORIGIN" />	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                frameOptions {                    sameOrigin = true                }            }        }    }}----====If you do not want the defaults to be added and want explicit control over what should be used, you can disable the defaults.The next code listing shows how to do so.If you use Spring Security's configuration, the following adds only xref:features/exploits/headers.adoc#headers-cache-control[Cache Control]:.Customize Cache Control Headers====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				// do not use any default headers unless explicitly listed				.defaultsDisabled()				.cacheControl(withDefaults())			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers defaults-disabled="true">		<cache-control/>	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                // do not use any default headers unless explicitly listed                defaultsDisabled = true                cacheControl {                }            }        }    }}----====If necessary, you can disable all of the HTTP Security response headers with the following configuration:.Disable All HTTP Security Headers====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers.disable());	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers disabled="true" /></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                disable()            }        }    }}----====[[servlet-headers-cache-control]]== Cache ControlSpring Security includes xref:features/exploits/headers.adoc#headers-cache-control[Cache Control] headers by default.However, if you actually want to cache specific responses, your application can selectively invoke https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html#setHeader(java.lang.String,java.lang.String)[`HttpServletResponse.setHeader(String,String)`] to override the header set by Spring Security.You can use this to ensure that content (such as CSS, JavaScript, and images) is properly cached.When you use Spring Web MVC, this is typically done within your configuration.You can find details on how to do this in the https://docs.spring.io/spring/docs/5.0.0.RELEASE/spring-framework-reference/web.html#mvc-config-static-resources[Static Resources] portion of the Spring Reference documentationIf necessary, you can also disable Spring Security's cache control HTTP response headers..Cache Control Disabled====.Java[source,java,role="primary"]----@Configuration@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) {		http			// ...			.headers(headers -> headers				.cacheControl(cache -> cache.disable())			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<cache-control disabled="true"/>	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {       http {            headers {                cacheControl {                    disable()                }            }        }    }}----====[[servlet-headers-content-type-options]]== Content Type OptionsSpring Security includes xref:features/exploits/headers.adoc#headers-content-type-options[Content-Type] headers by default.However, you can disable it:.Content Type Options Disabled====.Java[source,java,role="primary"]----@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends		WebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) {		http			// ...			.headers(headers -> headers				.contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<content-type-options disabled="true"/>	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {       http {            headers {                contentTypeOptions {                    disable()                }            }        }    }}----====[[servlet-headers-hsts]]== HTTP Strict Transport Security (HSTS)By default, Spring Security provides the xref:features/exploits/headers.adoc#headers-hsts[Strict Transport Security] header.However, you can explicitly customize the results.The following example explicitly provides HSTS:.Strict Transport Security====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				.httpStrictTransportSecurity(hsts -> hsts					.includeSubDomains(true)					.preload(true)					.maxAgeInSeconds(31536000)				)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<hsts			include-subdomains="true"			max-age-seconds="31536000"			preload="true" />	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            headers {                httpStrictTransportSecurity {                    includeSubDomains = true                    preload = true                    maxAgeInSeconds = 31536000                }            }        }    }}----====[[servlet-headers-hpkp]]== HTTP Public Key Pinning (HPKP)Spring Security provides servlet support for xref:features/exploits/headers.adoc#headers-hpkp[HTTP Public Key Pinning], but it is xref:features/exploits/headers.adoc#headers-hpkp-deprecated[no longer recommended].You can enable HPKP headers with the following configuration:.HTTP Public Key Pinning====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				.httpPublicKeyPinning(hpkp -> hpkp					.includeSubDomains(true)					.reportUri("https://example.net/pkp-report")					.addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=", "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=")				)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<hpkp			include-subdomains="true"			report-uri="https://example.net/pkp-report">			<pins>				<pin algorithm="sha256">d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=</pin>				<pin algorithm="sha256">E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=</pin>			</pins>		</hpkp>	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            headers {                httpPublicKeyPinning {                    includeSubDomains = true                    reportUri = "https://example.net/pkp-report"                    pins = mapOf("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=" to "sha256",                            "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" to "sha256")                }            }        }    }}----====[[servlet-headers-frame-options]]== X-Frame-OptionsBy default, Spring Security instructs browsers to block reflected XSS attacks by using the xref:features/exploits/headers.adoc#headers-frame-options[X-Frame-Options].For example, the following configuration specifies that Spring Security should no longer instruct browsers to block the content:.X-Frame-Options: SAMEORIGIN====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				.frameOptions(frameOptions -> frameOptions					.sameOrigin()				)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<frame-options		policy="SAMEORIGIN" />	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            headers {                frameOptions {                    sameOrigin = true                }            }        }    }}----====[[servlet-headers-xss-protection]]== X-XSS-ProtectionBy default, Spring Security instructs browsers to block reflected XSS attacks by using the <<headers-xss-protection,X-XSS-Protection header>.However, you can change this default.For example, the following configuration specifies that Spring Security should no longer instruct browsers to block the content:.X-XSS-Protection Customization====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				.xssProtection(xss -> xss					.block(false)				)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<xss-protection block="false"/>	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        // ...        http {            headers {                xssProtection {                    block = false                }            }        }    }}----====[[servlet-headers-csp]]== Content Security Policy (CSP)Spring Security does not add xref:features/exploits/headers.adoc#headers-csp[Content Security Policy] by default, because a reasonable default is impossible to know without knowing the context of the application.The web application author must declare the security policy (or policies) to enforce or monitor for the protected resources.Consider the following security policy:.Content Security Policy Example====[source,http]----Content-Security-Policy: script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/----====Given the preceding security policy, you can enable the CSP header:.Content Security Policy====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) {		http			// ...			.headers(headers -> headers				.contentSecurityPolicy(csp -> csp					.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")				)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<content-security-policy			policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/" />	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                contentSecurityPolicy {                    policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"                }            }        }    }}----====To enable the CSP `report-only` header, provide the following configuration:.Content Security Policy Report Only====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extends		WebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				.contentSecurityPolicy(csp -> csp					.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")					.reportOnly()				)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<content-security-policy			policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"			report-only="true" />	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                contentSecurityPolicy {                    policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"                    reportOnly = true                }            }        }    }}----====[[servlet-headers-referrer]]== Referrer PolicySpring Security does not add xref:features/exploits/headers.adoc#headers-referrer[Referrer Policy] headers by default.You can enable the Referrer Policy header by using the configuration:.Referrer Policy====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) {		http			// ...			.headers(headers -> headers				.referrerPolicy(referrer -> referrer					.policy(ReferrerPolicy.SAME_ORIGIN)				)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<referrer-policy policy="same-origin" />	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                referrerPolicy {                    policy = ReferrerPolicy.SAME_ORIGIN                }            }        }    }}----====[[servlet-headers-feature]]== Feature PolicySpring Security does not add xref:features/exploits/headers.adoc#headers-feature[Feature Policy] headers by default.Consider the following `Feature-Policy` header:.Feature-Policy Example====[source]----Feature-Policy: geolocation 'self'----====You can enable the preceding feature policy header by using the following configuration:.Feature-Policy====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				.featurePolicy("geolocation 'self'")			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<feature-policy policy-directives="geolocation 'self'" />	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                featurePolicy("geolocation 'self'")            }        }    }}----====[[servlet-headers-permissions]]== Permissions PolicySpring Security does not add xref:features/exploits/headers.adoc#headers-permissions[Permissions Policy] headers by default.Consider the following `Permissions-Policy` header:.Permissions-Policy Example====[source]----Permissions-Policy: geolocation=(self)----====You can enable the preceding permissions policy header using the following configuration:.Permissions-Policy====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				.permissionsPolicy(permissions -> permissions					.policy("geolocation=(self)")				)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<permissions-policy policy="geolocation=(self)" />	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                permissionPolicy {                    policy = "geolocation=(self)"                }            }        }    }}----====[[servlet-headers-clear-site-data]]== Clear Site DataSpring Security does not add xref:features/exploits/headers.adoc#headers-clear-site-data[Clear-Site-Data] headers by default.Consider the following Clear-Site-Data header:.Clear-Site-Data Example====----Clear-Site-Data: "cache", "cookies"----====You can send the preceding header on log out with the following configuration:.Clear-Site-Data====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.logout()				.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES)));	}}----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            logout {                addLogoutHandler(HeaderWriterLogoutHandler(ClearSiteDataHeaderWriter(CACHE, COOKIES)))            }        }    }}----====[[servlet-headers-custom]]== Custom HeadersSpring Security has mechanisms to make it convenient to add the more common security headers to your application.However, it also provides hooks to enable adding custom headers.[[servlet-headers-static]]=== Static HeadersThere may be times when you wish to inject custom security headers that are not supported out of the box into your application.Consider the following custom security header:[source]----X-Custom-Security-Header: header-value----Given the preceding header, you could add the headers to the response by using the following configuration:.StaticHeadersWriter====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				.addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"))			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<header name="X-Custom-Security-Header" value="header-value"/>	</headers></http>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                addHeaderWriter(StaticHeadersWriter("X-Custom-Security-Header","header-value"))            }        }    }}----====[[servlet-headers-writer]]=== Headers WriterWhen the namespace or Java configuration does not support the headers you want, you can create a custom `HeadersWriter` instance or even provide a custom implementation of the `HeadersWriter`.The next example use a custom instance of `XFrameOptionsHeaderWriter`.If you wanted to explicitly configure <<servlet-headers-frame-options>>, you could do so with the following configuration:.Headers Writer====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		http			// ...			.headers(headers -> headers				.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<header ref="frameOptionsWriter"/>	</headers></http><!-- Requires the c-namespace.See https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-c-namespace--><beans:bean id="frameOptionsWriter"	class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"	c:frameOptionsMode="SAMEORIGIN"/>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        http {            // ...            headers {                addHeaderWriter(XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))            }        }    }}----====[[headers-delegatingrequestmatcherheaderwriter]]=== DelegatingRequestMatcherHeaderWriterAt times, you may want to write a header only for certain requests.For example, perhaps you want to protect only your login page from being framed.You could use the `DelegatingRequestMatcherHeaderWriter` to do so.The following configuration example uses `DelegatingRequestMatcherHeaderWriter`:.DelegatingRequestMatcherHeaderWriter Java Configuration====.Java[source,java,role="primary"]----@EnableWebSecuritypublic class WebSecurityConfig extendsWebSecurityConfigurerAdapter {	@Override	protected void configure(HttpSecurity http) throws Exception {		RequestMatcher matcher = new AntPathRequestMatcher("/login");		DelegatingRequestMatcherHeaderWriter headerWriter =			new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());		http			// ...			.headers(headers -> headers				.frameOptions(frameOptions -> frameOptions.disable())				.addHeaderWriter(headerWriter)			);	}}----.XML[source,xml,role="secondary"]----<http>	<!-- ... -->	<headers>		<frame-options disabled="true"/>		<header ref="headerWriter"/>	</headers></http><beans:bean id="headerWriter"	class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">	<beans:constructor-arg>		<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher"			c:pattern="/login"/>	</beans:constructor-arg>	<beans:constructor-arg>		<beans:bean			class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"/>	</beans:constructor-arg></beans:bean>----.Kotlin[source,kotlin,role="secondary"]----@EnableWebSecurityclass SecurityConfig : WebSecurityConfigurerAdapter() {    override fun configure(http: HttpSecurity) {        val matcher: RequestMatcher = AntPathRequestMatcher("/login")        val headerWriter = DelegatingRequestMatcherHeaderWriter(matcher, XFrameOptionsHeaderWriter())       http {            headers {                frameOptions {                    disable()                }                addHeaderWriter(headerWriter)            }        }    }}----====
 |