1
0
mirror of synced 2026-08-05 17:57:15 +00:00

Support nested builder in DSL for reactive apps

Fixes: gh-7107
This commit is contained in:
Eleftheria Stein
2019-07-22 09:31:10 -04:00
committed by Rob Winch
parent ab6440db10
commit a288ce4b00
27 changed files with 1988 additions and 202 deletions
@@ -28,10 +28,10 @@ The following will disable the CORS integration within Spring Security:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.cors().disable();
.cors(cors -> cors.disable());
return http.build();
}
----
@@ -53,12 +53,20 @@ You can easily do this with the following Java Configuration:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.hsts().disable()
.frameOptions().mode(Mode.SAMEORIGIN);
.headers(headers ->
headers
.hsts(hsts ->
hsts
.disable()
)
.frameOptions(frameOptions ->
frameOptions
.mode(Mode.SAMEORIGIN)
)
);
return http.build();
}
----
@@ -72,11 +80,13 @@ If necessary, you can disable all of the HTTP Security response headers with the
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.disable();
.headers(headers ->
headers
.disable()
);
return http.build();
}
----
@@ -104,11 +114,13 @@ You can also disable cache control using the following Java Configuration:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.cache().disable();
.headers(headers ->
headers
.cache(cache -> cache.disable())
);
return http.build();
}
----
@@ -143,11 +155,13 @@ However, if need to disable the header, the following may be used:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.contentTypeOptions().disable();
.headers(headers ->
headers
.contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())
);
return http.build();
}
----
@@ -188,14 +202,18 @@ You can customize HSTS headers with Java Configuration:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.hsts()
.includeSubdomains(true)
.preload(true)
.maxAge(Duration.ofDays(365));
.headers(headers ->
headers
.hsts(hsts ->
hsts
.includeSubdomains(true)
.preload(true)
.maxAge(Duration.ofDays(365))
)
);
return http.build();
}
----
@@ -232,12 +250,16 @@ You can customize X-Frame-Options with Java Configuration using the following:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.frameOptions()
.mode(SAMEORIGIN);
.headers(headers ->
headers
.frameOptions(frameOptions ->
frameOptions
.mode(SAMEORIGIN)
)
);
return http.build();
}
----
@@ -264,12 +286,13 @@ However, we can customize with Java Configuration with the following:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.xssProtection()
.disable();
.headers(headers ->
headers
.xssProtection(xssProtection -> xssProtection.disable())
);
return http.build();
}
----
@@ -345,11 +368,16 @@ You can enable the CSP header using Java configuration as shown below:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/");
.headers(headers ->
headers
.contentSecurityPolicy(contentSecurityPolicy ->
contentSecurityPolicy
.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
)
);
return http.build();
}
----
@@ -359,12 +387,17 @@ To enable the CSP _'report-only'_ header, provide the following Java configurati
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
.reportOnly();
.headers(headers ->
headers
.contentSecurityPolicy(contentSecurityPolicy ->
contentSecurityPolicy
.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
.reportOnly()
)
);
return http.build();
}
----
@@ -405,11 +438,16 @@ You can enable the Referrer-Policy header using Java configuration as shown belo
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.referrerPolicy(ReferrerPolicy.SAME_ORIGIN);
.headers(headers ->
headers
.referrerPolicy(referrerPolicy ->
referrerPolicy
.policy(ReferrerPolicy.SAME_ORIGIN)
)
);
return http.build();
}
----
@@ -438,11 +476,13 @@ You can enable the Feature-Policy header using Java configuration as shown below
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.headers()
.featurePolicy("geolocation 'self'");
.headers(headers ->
headers
.featurePolicy("geolocation 'self'")
);
return http.build();
}
----
@@ -88,10 +88,11 @@ public class SecurityConfig {
return http
// Demonstrate that method security works
// Best practice to use both for defense in depth
.authorizeExchange()
.anyExchange().permitAll()
.and()
.httpBasic().and()
.authorizeExchange(exchanges ->
exchanges
.anyExchange().permitAll()
)
.httpBasic(withDefaults())
.build();
}
@@ -27,7 +27,7 @@ The next step is to instruct Spring Security that you wish to act as an OAuth2 C
SecurityWebFilterChain configure(ServerHttpSecurity http) throws Exception {
http
// ...
.oauth2Client();
.oauth2Client(withDefaults());
return http.build();
}
----
@@ -128,10 +128,10 @@ ReactiveClientRegistrationRepository clientRegistrations() {
}
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.oauth2Login();
.oauth2Login(withDefaults());
return http.build();
}
----
@@ -141,14 +141,16 @@ Additional configuration options can be seen below:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.oauth2Login()
.authenticationConverter(converter)
.authenticationManager(manager)
.authorizedClientRepository(authorizedClients)
.clientRegistrationRepository(clientRegistrations);
.oauth2Login(oauth2Login ->
oauth2Login
.authenticationConverter(converter)
.authenticationManager(manager)
.authorizedClientRepository(authorizedClients)
.clientRegistrationRepository(clientRegistrations)
);
return http.build();
}
----
@@ -121,14 +121,17 @@ The first is a `SecurityWebFilterChain` that configures the app as a resource se
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
return http.build();
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
.authorizeExchange(exchanges ->
exchanges
.anyExchange().authenticated()
)
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer
.jwt(withDefaults())
);
return http.build();
}
----
@@ -139,14 +142,17 @@ Replacing this is as simple as exposing the bean within the application:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
.authorizeExchange()
.pathMatchers("/message/**").hasAuthority("SCOPE_message:read")
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
.authorizeExchange(exchanges ->
exchanges
.pathMatchers("/message/**").hasAuthority("SCOPE_message:read")
.anyExchange().authenticated()
)
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer
.jwt(withDefaults())
);
return http.build();
}
----
@@ -177,15 +183,20 @@ An authorization server's JWK Set Uri can be configured <<webflux-oauth2-resourc
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwkSetUri("https://idp.example.com/.well-known/jwks.json");
return http.build();
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
.authorizeExchange(exchanges ->
exchanges
.anyExchange().authenticated()
)
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer
.jwt(jwt ->
jwt
.jwkSetUri("https://idp.example.com/.well-known/jwks.json")
)
);
return http.build();
}
----
@@ -199,14 +210,19 @@ More powerful than `jwkSetUri()` is `decoder()`, which will completely replace a
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.decoder(myCustomDecoder());
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
.authorizeExchange(exchanges ->
exchanges
.anyExchange().authenticated()
)
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer
.jwt(jwt ->
jwt
.decoder(myCustomDecoder())
)
);
return http.build();
}
----
@@ -240,15 +256,18 @@ This means that to protect an endpoint or method with a scope derived from a JWT
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.mvcMatchers("/contacts/**").hasAuthority("SCOPE_contacts")
.mvcMatchers("/messages/**").hasAuthority("SCOPE_messages")
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
.authorizeExchange(exchanges ->
exchanges
.mvcMatchers("/contacts/**").hasAuthority("SCOPE_contacts")
.mvcMatchers("/messages/**").hasAuthority("SCOPE_messages")
.anyExchange().authenticated()
)
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer
.jwt(withDefaults())
);
return http.build();
}
----
@@ -273,15 +292,20 @@ To this end, the DSL exposes `jwtAuthenticationConverter()`:
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(grantedAuthoritiesExtractor());
return http.build();
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
.authorizeExchange(exchanges ->
exchanges
.anyExchange().authenticated()
)
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer
.jwt(jwt ->
jwt
.jwtAuthenticationConverter(grantedAuthoritiesExtractor())
)
);
return http.build();
}
Converter<Jwt, Mono<AbstractAuthenticationToken>> grantedAuthoritiesExtractor() {
@@ -7,10 +7,10 @@ Spring Security can be configured to perform a redirect to https using the follo
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.redirectToHttps();
.redirectToHttps(withDefaults());
return http.build();
}
----
@@ -22,11 +22,13 @@ For example, if the production environment adds a header named `X-Forwarded-Prot
[source,java]
----
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
// ...
.redirectToHttps()
.httpsRedirectWhen(e -> e.getRequest().getHeaders().containsKey("X-Forwarded-Proto"));
.redirectToHttps(redirectToHttps ->
redirectToHttps
.httpsRedirectWhen(e -> e.getRequest().getHeaders().containsKey("X-Forwarded-Proto"))
);
return http.build();
}
----
@@ -52,13 +52,14 @@ public class HelloWebfluxSecurityConfig {
}
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.httpBasic().and()
.formLogin();
.authorizeExchange(exchanges ->
exchanges
.anyExchange().authenticated()
)
.httpBasic(withDefaults())
.formLogin(withDefaults());
return http.build();
}
}
@@ -7,14 +7,14 @@ Below is an example of a reactive x509 security configuration:
[source,java]
----
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.x509()
.and()
.authorizeExchange()
.anyExchange().permitAll();
return http.build();
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) throws Exception {
http
.x509(withDefaults())
.authorizeExchange(exchanges ->
exchanges
.anyExchange().permitAll()
);
return http.build();
}
----
@@ -25,28 +25,28 @@ The next example demonstrates how these defaults can be overridden.
[source,java]
----
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
SubjectDnX509PrincipalExtractor principalExtractor =
new SubjectDnX509PrincipalExtractor();
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) throws Exception {
SubjectDnX509PrincipalExtractor principalExtractor =
new SubjectDnX509PrincipalExtractor();
principalExtractor.setSubjectDnRegex("OU=(.*?)(?:,|$)");
principalExtractor.setSubjectDnRegex("OU=(.*?)(?:,|$)");
ReactiveAuthenticationManager authenticationManager = authentication -> {
authentication.setAuthenticated("Trusted Org Unit".equals(authentication.getName()));
return Mono.just(authentication);
};
ReactiveAuthenticationManager authenticationManager = authentication -> {
authentication.setAuthenticated("Trusted Org Unit".equals(authentication.getName()));
return Mono.just(authentication);
};
// @formatter:off
http
.x509()
.principalExtractor(principalExtractor)
.authenticationManager(authenticationManager)
.and()
.authorizeExchange()
.anyExchange().authenticated();
// @formatter:on
return http.build();
http
.x509(x509 ->
x509
.principalExtractor(principalExtractor)
.authenticationManager(authenticationManager)
)
.authorizeExchange(exchanges ->
exchanges
.anyExchange().authenticated()
);
return http.build();
}
----