HelloWebfluxApplicationTests.java 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. *
  3. * * Copyright 2002-2017 the original author or authors.
  4. * *
  5. * * Licensed under the Apache License, Version 2.0 (the "License");
  6. * * you may not use this file except in compliance with the License.
  7. * * You may obtain a copy of the License at
  8. * *
  9. * * http://www.apache.org/licenses/LICENSE-2.0
  10. * *
  11. * * Unless required by applicable law or agreed to in writing, software
  12. * * distributed under the License is distributed on an "AS IS" BASIS,
  13. * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * * See the License for the specific language governing permissions and
  15. * * limitations under the License.
  16. *
  17. */
  18. package sample;
  19. import org.junit.Before;
  20. import org.junit.Test;
  21. import org.junit.runner.RunWith;
  22. import org.springframework.beans.factory.annotation.Autowired;
  23. import org.springframework.context.ApplicationContext;
  24. import org.springframework.http.HttpHeaders;
  25. import org.springframework.http.HttpStatus;
  26. import org.springframework.http.ResponseCookie;
  27. import org.springframework.security.web.server.header.ContentTypeOptionsHttpHeadersWriter;
  28. import org.springframework.test.context.ActiveProfiles;
  29. import org.springframework.test.context.ContextConfiguration;
  30. import org.springframework.test.context.junit4.SpringRunner;
  31. import org.springframework.test.web.reactive.server.ExchangeMutatorWebFilter;
  32. import org.springframework.test.web.reactive.server.ExchangeResult;
  33. import org.springframework.test.web.reactive.server.WebTestClient;
  34. import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
  35. import java.nio.charset.Charset;
  36. import java.util.Base64;
  37. import static org.springframework.security.test.web.reactive.server.SecurityExchangeMutators.withUser;
  38. import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication;
  39. /**
  40. * @author Rob Winch
  41. * @since 5.0
  42. */
  43. @RunWith(SpringRunner.class)
  44. @ContextConfiguration(classes = HelloWebfluxApplication.class)
  45. @ActiveProfiles("test")
  46. public class HelloWebfluxApplicationTests {
  47. @Autowired
  48. ApplicationContext context;
  49. WebTestClient rest;
  50. @Before
  51. public void setup() {
  52. this.rest = WebTestClient.bindToApplicationContext(context).build();
  53. }
  54. @Test
  55. public void basicRequired() throws Exception {
  56. this.rest
  57. .get()
  58. .uri("/principal")
  59. .exchange()
  60. .expectStatus().isUnauthorized();
  61. }
  62. @Test
  63. public void basicWorks() throws Exception {
  64. this.rest
  65. .filter(robsCredentials())
  66. .get()
  67. .uri("/principal")
  68. .exchange()
  69. .expectStatus().isOk()
  70. .expectBody().json("{\"username\":\"rob\"}");
  71. }
  72. @Test
  73. public void basicWhenPasswordInvalid401() throws Exception {
  74. this.rest
  75. .filter(invalidPassword())
  76. .get()
  77. .uri("/principal")
  78. .exchange()
  79. .expectStatus().isUnauthorized()
  80. .expectBody().isEmpty();
  81. }
  82. @Test
  83. public void authorizationAdmin403() throws Exception {
  84. this.rest
  85. .filter(robsCredentials())
  86. .get()
  87. .uri("/admin")
  88. .exchange()
  89. .expectStatus().isEqualTo(HttpStatus.FORBIDDEN)
  90. .expectBody().isEmpty();
  91. }
  92. @Test
  93. public void authorizationAdmin200() throws Exception {
  94. this.rest
  95. .filter(adminCredentials())
  96. .get()
  97. .uri("/admin")
  98. .exchange()
  99. .expectStatus().isOk();
  100. }
  101. @Test
  102. public void basicMissingUser401() throws Exception {
  103. this.rest
  104. .filter(basicAuthentication("missing-user", "password"))
  105. .get()
  106. .uri("/admin")
  107. .exchange()
  108. .expectStatus().isUnauthorized();
  109. }
  110. @Test
  111. public void basicInvalidPassword401() throws Exception {
  112. this.rest
  113. .filter(invalidPassword())
  114. .get()
  115. .uri("/admin")
  116. .exchange()
  117. .expectStatus().isUnauthorized();
  118. }
  119. @Test
  120. public void basicInvalidParts401() throws Exception {
  121. this.rest
  122. .get()
  123. .uri("/admin")
  124. .header("Authorization", "Basic " + base64Encode("no colon"))
  125. .exchange()
  126. .expectStatus().isUnauthorized();
  127. }
  128. @Test
  129. public void sessionWorks() throws Exception {
  130. ExchangeResult result = this.rest
  131. .filter(robsCredentials())
  132. .get()
  133. .uri("/principal")
  134. .exchange()
  135. .returnResult(String.class);
  136. ResponseCookie session = result.getResponseCookies().getFirst("SESSION");
  137. this.rest
  138. .get()
  139. .uri("/principal")
  140. .cookie(session.getName(), session.getValue())
  141. .exchange()
  142. .expectStatus().isOk();
  143. }
  144. @Test
  145. public void mockSupport() throws Exception {
  146. ExchangeMutatorWebFilter exchangeMutator = new ExchangeMutatorWebFilter(withUser());
  147. WebTestClient mockRest = WebTestClient.bindToApplicationContext(this.context).webFilter(exchangeMutator).build();
  148. mockRest
  149. .get()
  150. .uri("/principal")
  151. .exchange()
  152. .expectStatus().isOk();
  153. this.rest
  154. .get()
  155. .uri("/principal")
  156. .exchange()
  157. .expectStatus().isUnauthorized();
  158. }
  159. @Test
  160. public void me() throws Exception {
  161. this.rest
  162. .filter(robsCredentials())
  163. .get()
  164. .uri("/me")
  165. .exchange()
  166. .expectStatus().isOk()
  167. .expectBody().json("{\"username\" : \"rob\"}");
  168. }
  169. @Test
  170. public void monoMe() throws Exception {
  171. this.rest
  172. .filter(robsCredentials())
  173. .get()
  174. .uri("/mono/me")
  175. .exchange()
  176. .expectStatus().isOk()
  177. .expectBody().json("{\"username\" : \"rob\"}");
  178. }
  179. @Test
  180. public void principal() throws Exception {
  181. this.rest
  182. .filter(robsCredentials())
  183. .get()
  184. .uri("/principal")
  185. .exchange()
  186. .expectStatus().isOk()
  187. .expectBody().json("{\"username\" : \"rob\"}");
  188. }
  189. @Test
  190. public void headers() throws Exception {
  191. this.rest
  192. .filter(robsCredentials())
  193. .get()
  194. .uri("/principal")
  195. .exchange()
  196. .expectHeader().valueEquals(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate")
  197. .expectHeader().valueEquals(HttpHeaders.EXPIRES, "0")
  198. .expectHeader().valueEquals(HttpHeaders.PRAGMA, "no-cache")
  199. .expectHeader().valueEquals(ContentTypeOptionsHttpHeadersWriter.X_CONTENT_OPTIONS, ContentTypeOptionsHttpHeadersWriter.NOSNIFF);
  200. }
  201. private ExchangeFilterFunction robsCredentials() {
  202. return basicAuthentication("rob","rob");
  203. }
  204. private ExchangeFilterFunction invalidPassword() {
  205. return basicAuthentication("rob","INVALID");
  206. }
  207. private ExchangeFilterFunction adminCredentials() {
  208. return basicAuthentication("admin","admin");
  209. }
  210. private String base64Encode(String value) {
  211. return Base64.getEncoder().encodeToString(value.getBytes(Charset.defaultCharset()));
  212. }
  213. }