Commit 8600bd72 authored by Madhura Bhave's avatar Madhura Bhave

Upgrade to Spring Security 5.0.0.BUILD-SNAPSHOT

Following some changes in the latest snapshot this includes:
- Some updates to oauth2 client auto-config
- Security auto-config no longer relies on GlobalAuthenticationConfigurerAdapter
- Remove reactive security starter

Closes gh-10704
parent eb446d07
......@@ -523,11 +523,6 @@
<artifactId>spring-security-data</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-webflux</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt-jose</artifactId>
......
......@@ -27,7 +27,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
/**
......@@ -42,7 +42,7 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
*/
@Configuration
@ConditionalOnClass({ AuthenticationManager.class,
GlobalAuthenticationConfigurerAdapter.class })
EnableWebSecurity.class })
@EnableConfigurationProperties(SecurityProperties.class)
@Import({ SpringBootWebSecurityConfiguration.class, WebSecurityEnablerConfiguration.class,
AuthenticationManagerConfiguration.class, SecurityDataConfiguration.class })
......
......@@ -16,14 +16,12 @@
package org.springframework.boot.autoconfigure.security;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
......@@ -36,7 +34,6 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
* @author Madhura Bhave
* @since 2.0.0
*/
@ConditionalOnClass(EnableWebSecurity.class)
@ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
public class SpringBootWebSecurityConfiguration {
......
......@@ -17,7 +17,6 @@
package org.springframework.boot.autoconfigure.security;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
......@@ -34,7 +33,6 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
* @since 2.0.0
*/
@ConditionalOnBean(WebSecurityConfigurerAdapter.class)
@ConditionalOnClass(EnableWebSecurity.class)
@ConditionalOnMissingBean(WebSecurityConfiguration.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@EnableWebSecurity
......
......@@ -76,7 +76,7 @@ final class OAuth2ClientPropertiesRegistrationAdapter {
throw new IllegalStateException(getErrorMessage(configuredProviderId, registrationId));
}
Builder builder = (provider != null ? provider.getBuilder(registrationId)
: new Builder(registrationId));
: ClientRegistration.withRegistrationId(registrationId));
if (providers.containsKey(providerId)) {
return getBuilder(builder, providers.get(providerId));
}
......
......@@ -27,15 +27,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.core.userdetails.MapUserDetailsRepository;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsRepository;
/**
* Default user {@link Configuration} for a reactive web application. Configures a
* {@link UserDetailsRepository} with a default user and generated password. This
* backs-off completely if there is a bean of type {@link UserDetailsRepository} or
* {@link ReactiveUserDetailsService} with a default user and generated password. This
* backs-off completely if there is a bean of type {@link ReactiveUserDetailsService} or
* {@link ReactiveAuthenticationManager}.
*
* @author Madhura Bhave
......@@ -44,7 +44,7 @@ import org.springframework.security.core.userdetails.UserDetailsRepository;
@Configuration
@ConditionalOnClass({ ReactiveAuthenticationManager.class })
@ConditionalOnMissingBean({ ReactiveAuthenticationManager.class,
UserDetailsRepository.class })
ReactiveUserDetailsService.class })
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
public class ReactiveAuthenticationManagerConfiguration {
......@@ -52,11 +52,11 @@ public class ReactiveAuthenticationManagerConfiguration {
.getLog(ReactiveAuthenticationManagerConfiguration.class);
@Bean
public MapUserDetailsRepository userDetailsRepository() {
public MapReactiveUserDetailsService reactiveUserDetailsService() {
String password = UUID.randomUUID().toString();
logger.info(String.format("%n%nUsing default security password: %s%n", password));
UserDetails user = User.withUsername("user").password(password).roles().build();
return new MapUserDetailsRepository(user);
return new MapReactiveUserDetailsService(user);
}
}
......@@ -25,9 +25,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.security.user.SecurityConfig;
import org.springframework.boot.test.context.SpringBootContextLoader;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
......@@ -57,7 +55,6 @@ public class JpaUserDetailsTests {
@Import({ EmbeddedDataSourceConfiguration.class, DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, SecurityAutoConfiguration.class })
@ComponentScan(basePackageClasses = SecurityConfig.class)
public static class Main {
}
......
......@@ -78,7 +78,7 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
assertThat(adapted.getAuthorizationGrantType()).isEqualTo(
org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(adapted.getRedirectUri()).isEqualTo("http://example.com/redirect");
assertThat(adapted.getScope()).containsExactly("scope");
assertThat(adapted.getScopes()).containsExactly("scope");
assertThat(adapted.getClientName()).isEqualTo("clientName");
}
......@@ -112,7 +112,7 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(adapted.getRedirectUri()).isEqualTo(
"{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}");
assertThat(adapted.getScope()).containsExactly("openid", "profile", "email",
assertThat(adapted.getScopes()).containsExactly("openid", "profile", "email",
"address", "phone");
assertThat(adapted.getClientName()).isEqualTo("Google");
}
......@@ -151,7 +151,7 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
assertThat(adapted.getAuthorizationGrantType()).isEqualTo(
org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(adapted.getRedirectUri()).isEqualTo("http://example.com/redirect");
assertThat(adapted.getScope()).containsExactly("scope");
assertThat(adapted.getScopes()).containsExactly("scope");
assertThat(adapted.getClientName()).isEqualTo("clientName");
}
......@@ -196,7 +196,7 @@ public class OAuth2ClientPropertiesRegistrationAdapterTests {
org.springframework.security.oauth2.core.AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(adapted.getRedirectUri()).isEqualTo(
"{scheme}://{serverName}:{serverPort}{contextPath}/oauth2/authorize/code/{registrationId}");
assertThat(adapted.getScope()).containsExactly("openid", "profile", "email",
assertThat(adapted.getScopes()).containsExactly("openid", "profile", "email",
"address", "phone");
assertThat(adapted.getClientName()).isEqualTo("Google");
}
......
......@@ -36,7 +36,7 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.AuthorizationCodeAuthenticationFilter;
import org.springframework.security.oauth2.client.web.AuthorizationCodeRequestRedirectFilter;
import org.springframework.security.oauth2.client.web.AuthorizationRequestRedirectFilter;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;
......@@ -97,7 +97,7 @@ public class OAuth2WebSecurityConfigurationTests {
.getField(filterChains.get(0), "filters");
List<Filter> oauth2Filters = filters.stream()
.filter((f) -> f instanceof AuthorizationCodeAuthenticationFilter
|| f instanceof AuthorizationCodeRequestRedirectFilter)
|| f instanceof AuthorizationRequestRedirectFilter)
.collect(Collectors.toList());
return oauth2Filters.stream()
.filter((f) -> f instanceof AuthorizationCodeAuthenticationFilter)
......@@ -111,7 +111,7 @@ public class OAuth2WebSecurityConfigurationTests {
&& ObjectUtils.nullSafeEquals(reg1.getClientName(), reg2.getClientName());
result = result && ObjectUtils.nullSafeEquals(reg1.getClientSecret(),
reg2.getClientSecret());
result = result && ObjectUtils.nullSafeEquals(reg1.getScope(), reg2.getScope());
result = result && ObjectUtils.nullSafeEquals(reg1.getScopes(), reg2.getScopes());
result = result && ObjectUtils.nullSafeEquals(reg1.getRedirectUri(),
reg2.getRedirectUri());
result = result && ObjectUtils.nullSafeEquals(reg1.getRegistrationId(),
......@@ -154,7 +154,7 @@ public class OAuth2WebSecurityConfigurationTests {
}
private ClientRegistration getClientRegistration(String id, String userInfoUri) {
ClientRegistration.Builder builder = new ClientRegistration.Builder(id);
ClientRegistration.Builder builder = ClientRegistration.withRegistrationId(id);
builder.clientName("foo").clientId("foo")
.clientAuthenticationMethod(
org.springframework.security.oauth2.core.ClientAuthenticationMethod.BASIC)
......
......@@ -29,14 +29,14 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.config.annotation.web.reactive.HttpSecurityConfiguration;
import org.springframework.security.config.annotation.web.reactive.ServerHttpSecurityConfiguration;
import org.springframework.security.config.annotation.web.reactive.WebFluxSecurityConfiguration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.MapUserDetailsRepository;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsRepository;
import org.springframework.security.web.server.WebFilterChainFilter;
import org.springframework.security.web.server.WebFilterChainProxy;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
......@@ -58,11 +58,11 @@ public class ReactiveSecurityAutoConfigurationTests {
.withConfiguration(
AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
.run((context) -> {
assertThat(context).getBean(HttpSecurityConfiguration.class)
assertThat(context).getBean(ServerHttpSecurityConfiguration.class)
.isNotNull();
assertThat(context).getBean(WebFluxSecurityConfiguration.class)
.isNotNull();
assertThat(context).getBean(WebFilterChainFilter.class).isNotNull();
assertThat(context).getBean(WebFilterChainProxy.class).isNotNull();
});
}
......@@ -72,9 +72,9 @@ public class ReactiveSecurityAutoConfigurationTests {
.withConfiguration(
AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
.run((context) -> {
UserDetailsRepository userDetailsRepository = context
.getBean(UserDetailsRepository.class);
assertThat(userDetailsRepository.findByUsername("user").block())
ReactiveUserDetailsService userDetailsService = context
.getBean(ReactiveUserDetailsService.class);
assertThat(userDetailsService.findByUsername("user").block())
.isNotNull();
});
}
......@@ -85,13 +85,13 @@ public class ReactiveSecurityAutoConfigurationTests {
.withConfiguration(
AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
.run((context) -> {
UserDetailsRepository userDetailsRepository = context
.getBean(UserDetailsRepository.class);
assertThat(userDetailsRepository.findByUsername("user").block())
ReactiveUserDetailsService userDetailsService = context
.getBean(ReactiveUserDetailsService.class);
assertThat(userDetailsService.findByUsername("user").block())
.isNull();
assertThat(userDetailsRepository.findByUsername("foo").block())
assertThat(userDetailsService.findByUsername("foo").block())
.isNotNull();
assertThat(userDetailsRepository.findByUsername("admin").block())
assertThat(userDetailsService.findByUsername("admin").block())
.isNotNull();
});
}
......@@ -103,7 +103,7 @@ public class ReactiveSecurityAutoConfigurationTests {
TestConfig.class)
.withConfiguration(
AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
.run((context) -> assertThat(context).getBean(UserDetailsRepository.class)
.run((context) -> assertThat(context).getBean(ReactiveUserDetailsService.class)
.isNull());
}
......@@ -127,12 +127,12 @@ public class ReactiveSecurityAutoConfigurationTests {
static class UserConfig {
@Bean
public MapUserDetailsRepository userDetailsRepository() {
public MapReactiveUserDetailsService userDetailsService() {
UserDetails foo = User.withUsername("foo").password("foo").roles("USER")
.build();
UserDetails admin = User.withUsername("admin").password("admin")
.roles("USER", "ADMIN").build();
return new MapUserDetailsRepository(foo, admin);
return new MapReactiveUserDetailsService(foo, admin);
}
}
......
/*
* Copyright 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.security.user;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
@EntityScan(basePackageClasses = User.class)
@EnableJpaRepositories(basePackageClasses = User.class)
public class SecurityConfig extends GlobalAuthenticationConfigurerAdapter {
protected final UserRepository userRepository;
public SecurityConfig(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
System.err.println("Global security config");
}
}
......@@ -154,7 +154,7 @@
<spring-plugin.version>1.2.0.RELEASE</spring-plugin.version>
<spring-restdocs.version>1.2.2.RELEASE</spring-restdocs.version>
<spring-retry.version>1.2.1.RELEASE</spring-retry.version>
<spring-security.version>5.0.0.M5</spring-security.version>
<spring-security.version>5.0.0.BUILD-SNAPSHOT</spring-security.version>
<spring-session.version>2.0.0.M5</spring-session.version>
<spring-session-data-mongodb.version>2.0.0.M4</spring-session-data-mongodb.version>
<spring-social.version>2.0.0.M4</spring-social.version>
......
......@@ -712,11 +712,6 @@
<artifactId>spring-security-test</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-webflux</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
......
......@@ -58,7 +58,6 @@
<module>spring-boot-starter-quartz</module>
<module>spring-boot-starter-reactor-netty</module>
<module>spring-boot-starter-security</module>
<module>spring-boot-starter-security-reactive</module>
<module>spring-boot-starter-social-facebook</module>
<module>spring-boot-starter-social-twitter</module>
<module>spring-boot-starter-social-linkedin</module>
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>${revision}</version>
</parent>
<artifactId>spring-boot-starter-security-reactive</artifactId>
<name>Spring Boot Security Reactive Starter</name>
<description>Starter for using reactive Spring Security</description>
<properties>
<main.basedir>${basedir}/../../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-webflux</artifactId>
</dependency>
</dependencies>
</project>
......@@ -27,7 +27,7 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security-reactive</artifactId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Test -->
<dependency>
......
......@@ -19,9 +19,9 @@ package sample.secure.webflux;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.userdetails.MapUserDetailsRepository;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsRepository;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
......@@ -41,8 +41,8 @@ public class SampleSecureWebFluxApplication {
}
@Bean
public UserDetailsRepository userDetailsRepository() {
return new MapUserDetailsRepository(
public ReactiveUserDetailsService userDetailsRepository() {
return new MapReactiveUserDetailsService(
User.withUsername("foo").password("password").roles("USER").build());
}
......
......@@ -18,19 +18,21 @@ package sample.security.method;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import org.springframework.boot.actuate.autoconfigure.security.EndpointRequest;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -67,14 +69,14 @@ public class SampleMethodSecurityApplication implements WebMvcConfigurer {
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
protected static class AuthenticationSecurity
extends GlobalAuthenticationConfigurerAdapter {
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password("admin")
.roles("ADMIN", "USER", "ACTUATOR").and().withUser("user")
.password("user").roles("USER");
protected static class AuthenticationSecurity {
@Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager() throws Exception {
String password = UUID.randomUUID().toString();
return new InMemoryUserDetailsManager(
User.withUsername("admin").password("admin").roles("ADMIN", "USER", "ACTUATOR").build(),
User.withUsername("user").password("user").roles("USER").build());
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment