浏览代码

Simplify webflux samples

Remove the custom user from the hellowebflux and hellowebfluxfn samples.
Rob Winch 8 年之前
父节点
当前提交
a79a81cd24
共有 20 个文件被更改,包括 80 次插入715 次删除
  1. 9 0
      core/src/main/java/org/springframework/security/authentication/MapUserDetailsRepository.java
  2. 5 5
      samples/javaconfig/hellowebflux/src/integration-test/java/sample/HelloWebfluxApplicationITests.java
  3. 0 51
      samples/javaconfig/hellowebflux/src/integration-test/java/sample/UserRepositoryTests.java
  4. 0 58
      samples/javaconfig/hellowebflux/src/main/java/sample/MapUserRepository.java
  5. 11 0
      samples/javaconfig/hellowebflux/src/main/java/sample/SecurityConfig.java
  6. 0 84
      samples/javaconfig/hellowebflux/src/main/java/sample/User.java
  7. 7 18
      samples/javaconfig/hellowebflux/src/main/java/sample/UserController.java
  8. 0 33
      samples/javaconfig/hellowebflux/src/main/java/sample/UserRepository.java
  9. 0 87
      samples/javaconfig/hellowebflux/src/main/java/sample/UserRepositoryUserDetailsRepository.java
  10. 8 8
      samples/javaconfig/hellowebflux/src/test/java/sample/HelloWebfluxApplicationTests.java
  11. 19 17
      samples/javaconfig/hellowebfluxfn/src/integration-test/java/sample/HelloWebfluxFnApplicationITests.java
  12. 0 51
      samples/javaconfig/hellowebfluxfn/src/integration-test/java/sample/UserRepositoryTests.java
  13. 0 21
      samples/javaconfig/hellowebfluxfn/src/main/java/sample/HelloWebfluxFnApplication.java
  14. 0 58
      samples/javaconfig/hellowebfluxfn/src/main/java/sample/MapUserRepository.java
  15. 11 0
      samples/javaconfig/hellowebfluxfn/src/main/java/sample/SecurityConfig.java
  16. 0 84
      samples/javaconfig/hellowebfluxfn/src/main/java/sample/User.java
  17. 1 11
      samples/javaconfig/hellowebfluxfn/src/main/java/sample/UserController.java
  18. 0 33
      samples/javaconfig/hellowebfluxfn/src/main/java/sample/UserRepository.java
  19. 0 87
      samples/javaconfig/hellowebfluxfn/src/main/java/sample/UserRepositoryUserDetailsRepository.java
  20. 9 9
      samples/javaconfig/hellowebfluxfn/src/test/java/sample/HelloWebfluxFnApplicationTests.java

+ 9 - 0
core/src/main/java/org/springframework/security/authentication/MapUserDetailsRepository.java

@@ -18,6 +18,7 @@
 
 package org.springframework.security.authentication;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
 import java.util.function.Function;
@@ -37,6 +38,14 @@ import reactor.core.publisher.Mono;
 public class MapUserDetailsRepository implements UserDetailsRepository {
 	private final Map<String,UserDetails> users;
 
+	public MapUserDetailsRepository(Map<String,UserDetails> users) {
+		this.users = users;
+	}
+
+	public MapUserDetailsRepository(UserDetails... users) {
+		this(Arrays.asList(users));
+	}
+
 	public MapUserDetailsRepository(Collection<UserDetails> users) {
 		Assert.notEmpty(users, "users cannot be null or empty");
 		this.users = users.stream().collect(Collectors.toMap( u -> getKey(u.getName()), Function.identity()));

+ 5 - 5
samples/javaconfig/hellowebflux/src/integration-test/java/sample/HelloWebfluxApplicationITests.java

@@ -70,10 +70,10 @@ public class HelloWebfluxApplicationITests {
 		this.rest
 			.filter(robsCredentials())
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isOk()
-			.expectBody().json("[{\"id\":null,\"username\":\"rob\",\"password\":\"rob\",\"firstname\":\"Rob\",\"lastname\":\"Winch\"},{\"id\":null,\"username\":\"admin\",\"password\":\"admin\",\"firstname\":\"Admin\",\"lastname\":\"User\"}]");
+			.expectBody().json("{\"username\":\"rob\"}");
 	}
 
 	@Test
@@ -81,7 +81,7 @@ public class HelloWebfluxApplicationITests {
 		this.rest
 			.filter(invalidPassword())
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isUnauthorized()
 			.expectBody().isEmpty();
@@ -143,7 +143,7 @@ public class HelloWebfluxApplicationITests {
 		ExchangeResult result = this.rest
 				.filter(robsCredentials())
 				.get()
-				.uri("/users")
+				.uri("/principal")
 				.exchange()
 				.returnResult(String.class);
 
@@ -151,7 +151,7 @@ public class HelloWebfluxApplicationITests {
 
 		this.rest
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.header("Cookie", session)
 			.exchange()
 			.expectStatus().isOk();

+ 0 - 51
samples/javaconfig/hellowebflux/src/integration-test/java/sample/UserRepositoryTests.java

@@ -1,51 +0,0 @@
-/*
- * Copyright 2002-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 sample;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-/**
- *
- * @author Rob Winch
- * @since 5.0
- */
-@SuppressWarnings("unused")
-@RunWith(SpringRunner.class)
-@ContextConfiguration(classes = HelloWebfluxApplication.class)
-@TestPropertySource(properties = "server.port=0")
-public class UserRepositoryTests {
-
-	@Autowired UserRepository repository;
-
-	String robUsername = "rob";
-
-	@Test
-	public void findByUsernameWhenUsernameMatchesThenFound() {
-		assertThat(repository.findByUsername(this.robUsername).block()).isNotNull();
-	}
-
-	@Test
-	public void findByUsernameWhenUsernameDoesNotMatchThenFound() {
-		assertThat(repository.findByUsername(this.robUsername + "NOTFOUND").block()).isNull();
-	}
-}

+ 0 - 58
samples/javaconfig/hellowebflux/src/main/java/sample/MapUserRepository.java

@@ -1,58 +0,0 @@
-/*
- *
- *  * Copyright 2002-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 sample;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.stereotype.Service;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * @author Rob Winch
- * @since 5.0
- */
-@Service
-public class MapUserRepository implements UserRepository {
-	private final Map<String,User> users = new HashMap<>();
-
-	public MapUserRepository() {
-		save(new User("rob", "rob", "Rob", "Winch")).block();
-		save(new User("admin", "admin", "Admin", "User")).block();
-	}
-
-	@Override
-	public Flux<User> findAll() {
-		return Flux.fromIterable(users.values());
-	}
-
-	@Override
-	public Mono<User> findByUsername(String username) {
-		User result = users.get(username);
-
-		return result == null ? Mono.empty() : Mono.just(result);
-	}
-
-	public Mono<User> save(User user) {
-		users.put(user.getUsername(), user);
-		return Mono.just(user);
-	}
-}

+ 11 - 0
samples/javaconfig/hellowebflux/src/main/java/sample/SecurityConfig.java

@@ -19,10 +19,13 @@
 package sample;
 
 import org.springframework.context.annotation.Bean;
+import org.springframework.security.authentication.MapUserDetailsRepository;
 import org.springframework.security.authorization.AuthorizationDecision;
 import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
 import org.springframework.security.config.web.server.HttpSecurity;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.web.server.authorization.AuthorizationContext;
 import org.springframework.web.server.WebFilter;
 import reactor.core.publisher.Mono;
@@ -49,4 +52,12 @@ public class SecurityConfig {
 			.map( a -> context.getVariables().get("user").equals(a.getName()))
 			.map( granted -> new AuthorizationDecision(granted));
 	}
+
+	@Bean
+	public MapUserDetailsRepository userDetailsRepository() {
+		UserDetails rob = User.withUsername("rob").password("rob").roles("USER").build();
+		UserDetails admin = User.withUsername("admin").password("admin").roles("USER","ADMIN").build();
+		return new MapUserDetailsRepository(rob, admin);
+	}
+
 }

+ 0 - 84
samples/javaconfig/hellowebflux/src/main/java/sample/User.java

@@ -1,84 +0,0 @@
-/*
- * Copyright 2002-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 sample;
-
-/**
- * @author Rob Winch
- * @since 5.0
- */
-public class User {
-
-	private Long id;
-	private String username;
-	private String password;
-	private String firstname;
-	private String lastname;
-
-	public User() {}
-
-	public User(User copy) {
-		this(copy.getUsername(), copy.getPassword(), copy.getFirstname(), copy.getLastname());
-	}
-
-	public User(String username, String password, String firstname, String lastname) {
-		super();
-		this.username = username;
-		this.password = password;
-		this.firstname = firstname;
-		this.lastname = lastname;
-	}
-
-	public Long getId() {
-		return id;
-	}
-
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public String getUsername() {
-		return username;
-	}
-
-	public void setUsername(String username) {
-		this.username = username;
-	}
-
-	public String getPassword() {
-		return password;
-	}
-
-	public void setPassword(String password) {
-		this.password = password;
-	}
-
-	public String getFirstname() {
-		return firstname;
-	}
-
-	public void setFirstname(String firstname) {
-		this.firstname = firstname;
-	}
-
-	public String getLastname() {
-		return lastname;
-	}
-
-	public void setLastname(String lastname) {
-		this.lastname = lastname;
-	}
-}

+ 7 - 18
samples/javaconfig/hellowebflux/src/main/java/sample/UserController.java

@@ -16,37 +16,31 @@
 
 package sample;
 
-import java.security.Principal;
-import java.util.Collections;
-import java.util.Map;
-
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RestController;
-
 import org.springframework.web.server.WebSession;
-import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Map;
+
 /**
  * @author Rob Winch
  * @since 5.0
  */
 @RestController
 public class UserController {
-	private final UserRepository users;
-
-	public UserController(UserRepository users) {
-		this.users = users;
-	}
 
 	@GetMapping("/me")
-	public Mono<Map<String,String>> me(@AuthenticationPrincipal User user) {
+	public Mono<Map<String,String>> me(@AuthenticationPrincipal UserDetails user) {
 		return me(Mono.just(user));
 	}
 
 	@GetMapping("/mono/me")
-	public Mono<Map<String,String>> me(@AuthenticationPrincipal Mono<User> user) {
+	public Mono<Map<String,String>> me(@AuthenticationPrincipal Mono<UserDetails> user) {
 		return user.flatMap( u -> Mono.just(Collections.singletonMap("username", u.getUsername())));
 	}
 
@@ -55,11 +49,6 @@ public class UserController {
 		return session.flatMap( s -> Mono.just(s.getAttributes()));
 	}
 
-	@GetMapping("/users")
-	public Flux<User> users() {
-		return this.users.findAll();
-	}
-
 	@GetMapping("/principal")
 	public Mono<Map<String,String>> principal(Principal principal) {
 		return principal(Mono.just(principal));

+ 0 - 33
samples/javaconfig/hellowebflux/src/main/java/sample/UserRepository.java

@@ -1,33 +0,0 @@
-/*
- * Copyright 2002-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 sample;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- *
- * @author Rob Winch
- * @since 5.0
- */
-public interface UserRepository {
-
-	Flux<User> findAll();
-
-	Mono<User> findByUsername(String username);
-
-	Mono<User> save(User user);
-}

+ 0 - 87
samples/javaconfig/hellowebflux/src/main/java/sample/UserRepositoryUserDetailsRepository.java

@@ -1,87 +0,0 @@
-/*
- * Copyright 2002-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 sample;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.springframework.security.authentication.UserDetailsRepository;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.stereotype.Component;
-
-import reactor.core.publisher.Mono;
-
-/**
- * @author Rob Winch
- * @since 5.0
- */
-@Component
-public class UserRepositoryUserDetailsRepository implements UserDetailsRepository {
-	private final UserRepository users;
-
-	public UserRepositoryUserDetailsRepository(UserRepository users) {
-		super();
-		this.users = users;
-	}
-
-	@Override
-	public Mono<UserDetails> findByUsername(String username) {
-		return this.users
-				.findByUsername(username)
-				.map(UserDetailsAdapter::new);
-	}
-
-	@SuppressWarnings("serial")
-	private static class UserDetailsAdapter extends User implements UserDetails {
-		private static List<GrantedAuthority> USER_ROLES = AuthorityUtils.createAuthorityList("ROLE_USER");
-		private static List<GrantedAuthority> ADMIN_ROLES = AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ROLE_USER");
-
-		private UserDetailsAdapter(User delegate) {
-			super(delegate);
-		}
-
-		@Override
-		public Collection<? extends GrantedAuthority> getAuthorities() {
-			return isAdmin() ? ADMIN_ROLES : USER_ROLES ;
-		}
-
-		private boolean isAdmin() {
-			return getUsername().contains("admin");
-		}
-
-		@Override
-		public boolean isAccountNonExpired() {
-			return true;
-		}
-
-		@Override
-		public boolean isAccountNonLocked() {
-			return true;
-		}
-
-		@Override
-		public boolean isCredentialsNonExpired() {
-			return true;
-		}
-
-		@Override
-		public boolean isEnabled() {
-			return true;
-		}
-	}
-}

+ 8 - 8
samples/javaconfig/hellowebflux/src/test/java/sample/HelloWebfluxApplicationTests.java

@@ -61,7 +61,7 @@ public class HelloWebfluxApplicationTests {
 	public void basicRequired() throws Exception {
 		this.rest
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isUnauthorized();
 	}
@@ -71,10 +71,10 @@ public class HelloWebfluxApplicationTests {
 		this.rest
 			.filter(robsCredentials())
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isOk()
-			.expectBody().json("[{\"id\":null,\"username\":\"rob\",\"password\":\"rob\",\"firstname\":\"Rob\",\"lastname\":\"Winch\"},{\"id\":null,\"username\":\"admin\",\"password\":\"admin\",\"firstname\":\"Admin\",\"lastname\":\"User\"}]");
+			.expectBody().json("{\"username\":\"rob\"}");
 	}
 
 	@Test
@@ -82,7 +82,7 @@ public class HelloWebfluxApplicationTests {
 		this.rest
 			.filter(invalidPassword())
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isUnauthorized()
 			.expectBody().isEmpty();
@@ -144,7 +144,7 @@ public class HelloWebfluxApplicationTests {
 		ExchangeResult result = this.rest
 				.filter(robsCredentials())
 				.get()
-				.uri("/users")
+				.uri("/principal")
 				.exchange()
 				.returnResult(String.class);
 
@@ -152,7 +152,7 @@ public class HelloWebfluxApplicationTests {
 
 		this.rest
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.cookie(session.getName(), session.getValue())
 			.exchange()
 			.expectStatus().isOk();
@@ -163,13 +163,13 @@ public class HelloWebfluxApplicationTests {
 		this.rest
 			.exchangeMutator( withUser() )
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isOk();
 
 		this.rest
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isUnauthorized();
 	}

+ 19 - 17
samples/javaconfig/hellowebfluxfn/src/integration-test/java/sample/HelloWebfluxFnApplicationITests.java

@@ -21,6 +21,7 @@ import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseCookie;
 import org.springframework.security.web.server.header.ContentTypeOptionsHttpHeadersWriter;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.TestPropertySource;
@@ -33,6 +34,7 @@ import java.nio.charset.Charset;
 import java.time.Duration;
 import java.util.Base64;
 
+import static org.springframework.security.test.web.reactive.server.SecurityExchangeMutators.withUser;
 import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication;
 
 /**
@@ -70,10 +72,10 @@ public class HelloWebfluxFnApplicationITests {
 		this.rest
 			.filter(robsCredentials())
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isOk()
-			.expectBody().json("[{\"id\":null,\"username\":\"rob\",\"password\":\"rob\",\"firstname\":\"Rob\",\"lastname\":\"Winch\"},{\"id\":null,\"username\":\"admin\",\"password\":\"admin\",\"firstname\":\"Admin\",\"lastname\":\"User\"}]");
+			.expectBody().json("{\"username\":\"rob\"}");
 	}
 
 	@Test
@@ -81,7 +83,7 @@ public class HelloWebfluxFnApplicationITests {
 		this.rest
 			.filter(invalidPassword())
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isUnauthorized()
 			.expectBody().isEmpty();
@@ -141,17 +143,17 @@ public class HelloWebfluxFnApplicationITests {
 	@Test
 	public void sessionWorks() throws Exception {
 		ExchangeResult result = this.rest
-				.filter(robsCredentials())
-				.get()
-				.uri("/users")
-				.exchange()
-				.returnResult(String.class);
+			.filter(robsCredentials())
+			.get()
+			.uri("/principal")
+			.exchange()
+			.returnResult(String.class);
 
 		String session = result.getResponseHeaders().getFirst("Set-Cookie");
 
 		this.rest
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.header("Cookie", session)
 			.exchange()
 			.expectStatus().isOk();
@@ -171,14 +173,14 @@ public class HelloWebfluxFnApplicationITests {
 	@Test
 	public void headers() throws Exception {
 		this.rest
-				.filter(robsCredentials())
-				.get()
-				.uri("/principal")
-				.exchange()
-				.expectHeader().valueEquals(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate")
-				.expectHeader().valueEquals(HttpHeaders.EXPIRES, "0")
-				.expectHeader().valueEquals(HttpHeaders.PRAGMA, "no-cache")
-				.expectHeader().valueEquals(ContentTypeOptionsHttpHeadersWriter.X_CONTENT_OPTIONS, ContentTypeOptionsHttpHeadersWriter.NOSNIFF);
+			.filter(robsCredentials())
+			.get()
+			.uri("/principal")
+			.exchange()
+			.expectHeader().valueEquals(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate")
+			.expectHeader().valueEquals(HttpHeaders.EXPIRES, "0")
+			.expectHeader().valueEquals(HttpHeaders.PRAGMA, "no-cache")
+			.expectHeader().valueEquals(ContentTypeOptionsHttpHeadersWriter.X_CONTENT_OPTIONS, ContentTypeOptionsHttpHeadersWriter.NOSNIFF);
 	}
 
 	private ExchangeFilterFunction robsCredentials() {

+ 0 - 51
samples/javaconfig/hellowebfluxfn/src/integration-test/java/sample/UserRepositoryTests.java

@@ -1,51 +0,0 @@
-/*
- * Copyright 2002-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 sample;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-/**
- *
- * @author Rob Winch
- * @since 5.0
- */
-@SuppressWarnings("unused")
-@RunWith(SpringRunner.class)
-@ContextConfiguration(classes = HelloWebfluxFnApplication.class)
-@TestPropertySource(properties = "server.port=0")
-public class UserRepositoryTests {
-
-	@Autowired UserRepository repository;
-
-	String robUsername = "rob";
-
-	@Test
-	public void findByUsernameWhenUsernameMatchesThenFound() {
-		assertThat(repository.findByUsername(this.robUsername).block()).isNotNull();
-	}
-
-	@Test
-	public void findByUsernameWhenUsernameDoesNotMatchThenFound() {
-		assertThat(repository.findByUsername(this.robUsername + "NOTFOUND").block()).isNull();
-	}
-}

+ 0 - 21
samples/javaconfig/hellowebfluxfn/src/main/java/sample/HelloWebfluxFnApplication.java

@@ -16,40 +16,20 @@
 
 package sample;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.*;
-import org.springframework.core.ReactiveAdapterRegistry;
 import org.springframework.http.server.reactive.HttpHandler;
 import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
-import org.springframework.security.authentication.ReactiveAuthenticationManager;
-import org.springframework.security.authentication.UserDetailsRepositoryAuthenticationManager;
-import org.springframework.security.authorization.AuthorizationDecision;
-import org.springframework.security.config.web.server.AuthorizeExchangeBuilder;
-import org.springframework.security.config.web.server.HttpSecurity;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.web.reactive.result.method.annotation.AuthenticationPrincipalArgumentResolver;
-import org.springframework.security.web.server.authorization.AuthorizationContext;
-import org.springframework.security.web.server.context.WebSessionSecurityContextRepository;
-import org.springframework.web.reactive.DispatcherHandler;
 import org.springframework.web.reactive.config.EnableWebFlux;
-import org.springframework.web.reactive.config.WebFluxConfigurer;
 import org.springframework.web.reactive.function.server.HandlerStrategies;
 import org.springframework.web.reactive.function.server.RouterFunction;
 import org.springframework.web.reactive.function.server.RouterFunctions;
 import org.springframework.web.reactive.function.server.ServerResponse;
-import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
 import org.springframework.web.server.WebFilter;
-import reactor.core.publisher.Mono;
 import reactor.ipc.netty.NettyContext;
 import reactor.ipc.netty.http.server.HttpServer;
 
-import static org.springframework.http.MediaType.APPLICATION_JSON;
-import static org.springframework.security.config.web.server.HttpSecurity.http;
 import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
-import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
-import static org.springframework.web.reactive.function.server.RequestPredicates.contentType;
 import static org.springframework.web.reactive.function.server.RouterFunctions.route;
 
 /**
@@ -81,7 +61,6 @@ public class HelloWebfluxFnApplication {
 	public HttpHandler httpHandler(UserController userController, WebFilter springSecurityFilterChain) {
 		RouterFunction<ServerResponse> route = route(
 				GET("/principal"), userController::principal).andRoute(
-				GET("/users"), userController::users).andRoute(
 				GET("/admin"), userController::admin);
 
 		HandlerStrategies handlerStrategies = HandlerStrategies.builder()

+ 0 - 58
samples/javaconfig/hellowebfluxfn/src/main/java/sample/MapUserRepository.java

@@ -1,58 +0,0 @@
-/*
- *
- *  * Copyright 2002-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 sample;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.stereotype.Service;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * @author Rob Winch
- * @since 5.0
- */
-@Service
-public class MapUserRepository implements UserRepository {
-	private final Map<String,User> users = new HashMap<>();
-
-	public MapUserRepository() {
-		save(new User("rob", "rob", "Rob", "Winch")).block();
-		save(new User("admin", "admin", "Admin", "User")).block();
-	}
-
-	@Override
-	public Flux<User> findAll() {
-		return Flux.fromIterable(users.values());
-	}
-
-	@Override
-	public Mono<User> findByUsername(String username) {
-		User result = users.get(username);
-
-		return result == null ? Mono.empty() : Mono.just(result);
-	}
-
-	public Mono<User> save(User user) {
-		users.put(user.getUsername(), user);
-		return Mono.just(user);
-	}
-}

+ 11 - 0
samples/javaconfig/hellowebfluxfn/src/main/java/sample/SecurityConfig.java

@@ -19,10 +19,13 @@
 package sample;
 
 import org.springframework.context.annotation.Bean;
+import org.springframework.security.authentication.MapUserDetailsRepository;
 import org.springframework.security.authorization.AuthorizationDecision;
 import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
 import org.springframework.security.config.web.server.HttpSecurity;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.web.server.authorization.AuthorizationContext;
 import org.springframework.web.server.WebFilter;
 import reactor.core.publisher.Mono;
@@ -49,4 +52,12 @@ public class SecurityConfig {
 			.map( a -> context.getVariables().get("user").equals(a.getName()))
 			.map( granted -> new AuthorizationDecision(granted));
 	}
+
+	@Bean
+	public MapUserDetailsRepository userDetailsRepository() {
+		UserDetails rob = User.withUsername("rob").password("rob").roles("USER").build();
+		UserDetails admin = User.withUsername("admin").password("admin").roles("USER","ADMIN").build();
+		return new MapUserDetailsRepository(rob, admin);
+	}
+
 }

+ 0 - 84
samples/javaconfig/hellowebfluxfn/src/main/java/sample/User.java

@@ -1,84 +0,0 @@
-/*
- * Copyright 2002-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 sample;
-
-/**
- * @author Rob Winch
- * @since 5.0
- */
-public class User {
-
-	private Long id;
-	private String username;
-	private String password;
-	private String firstname;
-	private String lastname;
-
-	public User() {}
-
-	public User(User copy) {
-		this(copy.getUsername(), copy.getPassword(), copy.getFirstname(), copy.getLastname());
-	}
-
-	public User(String username, String password, String firstname, String lastname) {
-		super();
-		this.username = username;
-		this.password = password;
-		this.firstname = firstname;
-		this.lastname = lastname;
-	}
-
-	public Long getId() {
-		return id;
-	}
-
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public String getUsername() {
-		return username;
-	}
-
-	public void setUsername(String username) {
-		this.username = username;
-	}
-
-	public String getPassword() {
-		return password;
-	}
-
-	public void setPassword(String password) {
-		this.password = password;
-	}
-
-	public String getFirstname() {
-		return firstname;
-	}
-
-	public void setFirstname(String firstname) {
-		this.firstname = firstname;
-	}
-
-	public String getLastname() {
-		return lastname;
-	}
-
-	public void setLastname(String lastname) {
-		this.lastname = lastname;
-	}
-}

+ 1 - 11
samples/javaconfig/hellowebfluxfn/src/main/java/sample/UserController.java

@@ -18,6 +18,7 @@ package sample;
 
 import org.springframework.http.MediaType;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.User;
 import org.springframework.security.web.server.context.SecurityContextRepository;
 import org.springframework.security.web.server.context.WebSessionSecurityContextRepository;
 import org.springframework.stereotype.Component;
@@ -37,11 +38,6 @@ import java.util.Map;
 public class UserController {
 	private final SecurityContextRepository repo = new WebSessionSecurityContextRepository();
 
-	private final UserRepository users;
-
-	public UserController(UserRepository users) {
-		this.users = users;
-	}
 
 	public Mono<ServerResponse> principal(ServerRequest serverRequest) {
 		return serverRequest.principal().cast(Authentication.class).flatMap(p ->
@@ -50,12 +46,6 @@ public class UserController {
 				.syncBody(p.getPrincipal()));
 	}
 
-	public Mono<ServerResponse> users(ServerRequest serverRequest) {
-		return ServerResponse.ok()
-			.contentType(MediaType.APPLICATION_JSON)
-			.body(this.users.findAll(), User.class);
-	}
-
 	public Mono<ServerResponse> admin(ServerRequest serverRequest) {
 		return serverRequest.principal().cast(Authentication.class).flatMap(p ->
 			ServerResponse.ok()

+ 0 - 33
samples/javaconfig/hellowebfluxfn/src/main/java/sample/UserRepository.java

@@ -1,33 +0,0 @@
-/*
- * Copyright 2002-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 sample;
-
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- *
- * @author Rob Winch
- * @since 5.0
- */
-public interface UserRepository {
-
-	Flux<User> findAll();
-
-	Mono<User> findByUsername(String username);
-
-	Mono<User> save(User user);
-}

+ 0 - 87
samples/javaconfig/hellowebfluxfn/src/main/java/sample/UserRepositoryUserDetailsRepository.java

@@ -1,87 +0,0 @@
-/*
- * Copyright 2002-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 sample;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.springframework.security.authentication.UserDetailsRepository;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.AuthorityUtils;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.stereotype.Component;
-
-import reactor.core.publisher.Mono;
-
-/**
- * @author Rob Winch
- * @since 5.0
- */
-@Component
-public class UserRepositoryUserDetailsRepository implements UserDetailsRepository {
-	private final UserRepository users;
-
-	public UserRepositoryUserDetailsRepository(UserRepository users) {
-		super();
-		this.users = users;
-	}
-
-	@Override
-	public Mono<UserDetails> findByUsername(String username) {
-		return this.users
-				.findByUsername(username)
-				.map(UserDetailsAdapter::new);
-	}
-
-	@SuppressWarnings("serial")
-	private static class UserDetailsAdapter extends User implements UserDetails {
-		private static List<GrantedAuthority> USER_ROLES = AuthorityUtils.createAuthorityList("ROLE_USER");
-		private static List<GrantedAuthority> ADMIN_ROLES = AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ROLE_USER");
-
-		private UserDetailsAdapter(User delegate) {
-			super(delegate);
-		}
-
-		@Override
-		public Collection<? extends GrantedAuthority> getAuthorities() {
-			return isAdmin() ? ADMIN_ROLES : USER_ROLES ;
-		}
-
-		private boolean isAdmin() {
-			return getUsername().contains("admin");
-		}
-
-		@Override
-		public boolean isAccountNonExpired() {
-			return true;
-		}
-
-		@Override
-		public boolean isAccountNonLocked() {
-			return true;
-		}
-
-		@Override
-		public boolean isCredentialsNonExpired() {
-			return true;
-		}
-
-		@Override
-		public boolean isEnabled() {
-			return true;
-		}
-	}
-}

+ 9 - 9
samples/javaconfig/hellowebfluxfn/src/test/java/sample/HelloWebfluxFnApplicationTests.java

@@ -22,7 +22,6 @@ import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseCookie;
@@ -59,11 +58,12 @@ public class HelloWebfluxFnApplicationTests {
 		this.rest = WebTestClient.bindToHttpHandler(handler).build();
 	}
 
+
 	@Test
 	public void basicRequired() throws Exception {
 		this.rest
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isUnauthorized();
 	}
@@ -73,10 +73,10 @@ public class HelloWebfluxFnApplicationTests {
 		this.rest
 			.filter(robsCredentials())
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isOk()
-			.expectBody().json("[{\"id\":null,\"username\":\"rob\",\"password\":\"rob\",\"firstname\":\"Rob\",\"lastname\":\"Winch\"},{\"id\":null,\"username\":\"admin\",\"password\":\"admin\",\"firstname\":\"Admin\",\"lastname\":\"User\"}]");
+			.expectBody().json("{\"username\":\"rob\"}");
 	}
 
 	@Test
@@ -84,7 +84,7 @@ public class HelloWebfluxFnApplicationTests {
 		this.rest
 			.filter(invalidPassword())
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isUnauthorized()
 			.expectBody().isEmpty();
@@ -146,7 +146,7 @@ public class HelloWebfluxFnApplicationTests {
 		ExchangeResult result = this.rest
 			.filter(robsCredentials())
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.returnResult(String.class);
 
@@ -154,7 +154,7 @@ public class HelloWebfluxFnApplicationTests {
 
 		this.rest
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.cookie(session.getName(), session.getValue())
 			.exchange()
 			.expectStatus().isOk();
@@ -166,13 +166,13 @@ public class HelloWebfluxFnApplicationTests {
 		this.rest
 			.exchangeMutator( withUser() )
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isOk();
 
 		this.rest
 			.get()
-			.uri("/users")
+			.uri("/principal")
 			.exchange()
 			.expectStatus().isUnauthorized();
 	}