Skip to content

Commit be23268

Browse files
committed
Add redirectToHttps DSL Configurer
Closes gh-16679
1 parent 2d96fba commit be23268

File tree

8 files changed

+501
-6
lines changed

8 files changed

+501
-6
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.springframework.security.web.session.DisableEncodeUrlFilter;
5555
import org.springframework.security.web.session.ForceEagerSessionCreationFilter;
5656
import org.springframework.security.web.session.SessionManagementFilter;
57+
import org.springframework.security.web.transport.HttpsRedirectFilter;
5758
import org.springframework.web.filter.CorsFilter;
5859

5960
/**
@@ -78,6 +79,7 @@ final class FilterOrderRegistration {
7879
put(DisableEncodeUrlFilter.class, order.next());
7980
put(ForceEagerSessionCreationFilter.class, order.next());
8081
put(ChannelProcessingFilter.class, order.next());
82+
put(HttpsRedirectFilter.class, order.next());
8183
order.next(); // gh-8105
8284
put(WebAsyncManagerIntegrationFilter.class, order.next());
8385
put(SecurityContextHolderFilter.class, order.next());

config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java

+48
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import org.springframework.security.config.annotation.web.configurers.FormLoginConfigurer;
6060
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
6161
import org.springframework.security.config.annotation.web.configurers.HttpBasicConfigurer;
62+
import org.springframework.security.config.annotation.web.configurers.HttpsRedirectConfigurer;
6263
import org.springframework.security.config.annotation.web.configurers.JeeConfigurer;
6364
import org.springframework.security.config.annotation.web.configurers.LogoutConfigurer;
6465
import org.springframework.security.config.annotation.web.configurers.PasswordManagementConfigurer;
@@ -3145,6 +3146,53 @@ public HttpSecurity requiresChannel(
31453146
return HttpSecurity.this;
31463147
}
31473148

3149+
/**
3150+
* Configures channel security. In order for this configuration to be useful at least
3151+
* one mapping to a required channel must be provided.
3152+
*
3153+
* <h2>Example Configuration</h2>
3154+
*
3155+
* The example below demonstrates how to require HTTPS for every request. Only
3156+
* requiring HTTPS for some requests is supported, for example if you need to
3157+
* differentiate between local and production deployments.
3158+
*
3159+
* <pre>
3160+
* &#064;Configuration
3161+
* &#064;EnableWebSecurity
3162+
* public class RequireHttpsConfig {
3163+
*
3164+
* &#064;Bean
3165+
* public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
3166+
* http
3167+
* .authorizeHttpRequests((authorize) -&gt; authorize
3168+
* anyRequest().authenticated()
3169+
* )
3170+
* .formLogin(withDefaults())
3171+
* .redirectToHttps(withDefaults());
3172+
* return http.build();
3173+
* }
3174+
*
3175+
* &#064;Bean
3176+
* public UserDetailsService userDetailsService() {
3177+
* UserDetails user = User.withDefaultPasswordEncoder()
3178+
* .username(&quot;user&quot;)
3179+
* .password(&quot;password&quot;)
3180+
* .roles(&quot;USER&quot;)
3181+
* .build();
3182+
* return new InMemoryUserDetailsManager(user);
3183+
* }
3184+
* }
3185+
* </pre>
3186+
* @param httpsRedirectConfigurerCustomizer the {@link Customizer} to provide more
3187+
* options for the {@link HttpsRedirectConfigurer}
3188+
* @return the {@link HttpSecurity} for further customizations
3189+
*/
3190+
public HttpSecurity redirectToHttps(
3191+
Customizer<HttpsRedirectConfigurer<HttpSecurity>> httpsRedirectConfigurerCustomizer) throws Exception {
3192+
httpsRedirectConfigurerCustomizer.customize(getOrApply(new HttpsRedirectConfigurer<>()));
3193+
return HttpSecurity.this;
3194+
}
3195+
31483196
/**
31493197
* Configures HTTP Basic authentication.
31503198
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright 2002-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.config.annotation.web.configurers;
18+
19+
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
20+
import org.springframework.security.web.PortMapper;
21+
import org.springframework.security.web.transport.HttpsRedirectFilter;
22+
import org.springframework.security.web.util.matcher.OrRequestMatcher;
23+
import org.springframework.security.web.util.matcher.RequestMatcher;
24+
25+
/**
26+
* Specifies for what requests the application should redirect to HTTPS. When this
27+
* configurer is added, it redirects all HTTP requests by default to HTTPS.
28+
*
29+
* <h2>Security Filters</h2>
30+
*
31+
* The following Filters are populated
32+
*
33+
* <ul>
34+
* <li>{@link HttpsRedirectFilter}</li>
35+
* </ul>
36+
*
37+
* <h2>Shared Objects Created</h2>
38+
*
39+
* No shared objects are created.
40+
*
41+
* <h2>Shared Objects Used</h2>
42+
*
43+
* The following shared objects are used:
44+
*
45+
* <ul>
46+
* <li>{@link PortMapper} is used to configure {@link HttpsRedirectFilter}</li>
47+
* </ul>
48+
*
49+
* @param <H> the type of {@link HttpSecurityBuilder} that is being configured
50+
* @author Josh Cummings
51+
* @since 6.5
52+
*/
53+
public final class HttpsRedirectConfigurer<H extends HttpSecurityBuilder<H>>
54+
extends AbstractHttpConfigurer<HeadersConfigurer<H>, H> {
55+
56+
private RequestMatcher requestMatcher;
57+
58+
public HttpsRedirectConfigurer<H> requestMatchers(RequestMatcher... matchers) {
59+
this.requestMatcher = new OrRequestMatcher(matchers);
60+
return this;
61+
}
62+
63+
@Override
64+
public void configure(H http) throws Exception {
65+
HttpsRedirectFilter filter = new HttpsRedirectFilter();
66+
if (this.requestMatcher != null) {
67+
filter.setRequestMatcher(this.requestMatcher);
68+
}
69+
PortMapper mapper = http.getSharedObject(PortMapper.class);
70+
if (mapper != null) {
71+
filter.setPortMapper(mapper);
72+
}
73+
http.addFilter(filter);
74+
}
75+
76+
}

config/src/main/kotlin/org/springframework/security/config/annotation/web/HttpSecurityDsl.kt

+33
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,39 @@ class HttpSecurityDsl(private val http: HttpSecurity, private val init: HttpSecu
533533
this.http.requiresChannel(requiresChannelCustomizer)
534534
}
535535

536+
/**
537+
* Configures channel security. In order for this configuration to be useful at least
538+
* one mapping to a required channel must be provided.
539+
*
540+
* Example:
541+
*
542+
* The example below demonstrates how to require HTTPS for every request. Only
543+
* requiring HTTPS for some requests is supported, for example if you need to differentiate
544+
* between local and production deployments.
545+
*
546+
* ```
547+
* @Configuration
548+
* @EnableWebSecurity
549+
* class RequireHttpsConfig {
550+
*
551+
* @Bean
552+
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
553+
* http {
554+
* redirectToHttps { }
555+
* }
556+
* return http.build();
557+
* }
558+
* }
559+
* ```
560+
* @param httpsRedirectConfiguration custom configuration to apply to HTTPS redirect rules
561+
* @see [HttpsRedirectDsl]
562+
* @since 6.5
563+
*/
564+
fun redirectToHttps(httpsRedirectConfiguration: HttpsRedirectDsl.() -> Unit) {
565+
val httpsRedirectCustomizer = HttpsRedirectDsl().apply(httpsRedirectConfiguration).get()
566+
this.http.redirectToHttps(httpsRedirectCustomizer)
567+
}
568+
536569
/**
537570
* Adds X509 based pre authentication to an application
538571
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2002-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.security.config.annotation.web
18+
19+
import org.springframework.security.config.annotation.web.builders.HttpSecurity
20+
import org.springframework.security.config.annotation.web.configurers.HttpsRedirectConfigurer
21+
import org.springframework.security.web.PortMapper
22+
import org.springframework.security.web.util.matcher.RequestMatcher
23+
24+
/**
25+
* A Kotlin DSL to configure [ServerHttpSecurity] HTTPS redirection rules using idiomatic
26+
* Kotlin code.
27+
*
28+
* @author Eleftheria Stein
29+
* @since 5.4
30+
* @property portMapper the [PortMapper] that specifies a custom HTTPS port to redirect to.
31+
*/
32+
@SecurityMarker
33+
class HttpsRedirectDsl {
34+
var requestMatchers: Array<out RequestMatcher>? = null
35+
36+
internal fun get(): (HttpsRedirectConfigurer<HttpSecurity>) -> Unit {
37+
return { https ->
38+
requestMatchers?.also { https.requestMatchers(*requestMatchers!!) }
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)