From 07b1982690bfc786ef9585aa3e716a32e0f0e26b Mon Sep 17 00:00:00 2001 From: Marcus Da Coregio Date: Thu, 6 Apr 2023 11:59:11 -0300 Subject: [PATCH 1/2] Revert "Remove spring-session-sample-javaconfig-rest" This reverts commit b229103d8cfd735dd01afc3d59cf210e6e7ec5cd. Closes gh-2259 --- ...ring-session-sample-javaconfig-rest.gradle | 31 +++++ .../java/rest/RestMockMvcTests.java | 112 ++++++++++++++++ .../java/sample/RestTests.java | 125 ++++++++++++++++++ .../integration-test/java/sample/User.java | 34 +++++ .../main/java/sample/EmbeddedRedisConfig.java | 46 +++++++ .../main/java/sample/HttpSessionConfig.java | 44 ++++++ .../src/main/java/sample/Initializer.java | 25 ++++ .../src/main/java/sample/SecurityConfig.java | 58 ++++++++ .../main/java/sample/SecurityInitializer.java | 26 ++++ .../src/main/java/sample/mvc/MvcConfig.java | 31 +++++ .../main/java/sample/mvc/MvcInitializer.java | 46 +++++++ .../java/sample/mvc/RestDemoController.java | 49 +++++++ .../src/main/resources/logback.xml | 14 ++ .../main/resources/testcontainers.properties | 1 + .../src/main/webapp/META-INF/MANIFEST.MF | 0 15 files changed, 642 insertions(+) create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/spring-session-sample-javaconfig-rest.gradle create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/rest/RestMockMvcTests.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/sample/RestTests.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/sample/User.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/EmbeddedRedisConfig.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/HttpSessionConfig.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/Initializer.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/SecurityConfig.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/SecurityInitializer.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/MvcConfig.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/MvcInitializer.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/RestDemoController.java create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/resources/logback.xml create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/resources/testcontainers.properties create mode 100644 spring-session-samples/spring-session-sample-javaconfig-rest/src/main/webapp/META-INF/MANIFEST.MF diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/spring-session-sample-javaconfig-rest.gradle b/spring-session-samples/spring-session-sample-javaconfig-rest/spring-session-sample-javaconfig-rest.gradle new file mode 100644 index 000000000..e076ed32d --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/spring-session-sample-javaconfig-rest.gradle @@ -0,0 +1,31 @@ +plugins { + id "org.gretty" version "4.0.0" + id "io.spring.convention.spring-sample-war" +} + +dependencies { + implementation project(':spring-session-data-redis') + implementation "io.lettuce:lettuce-core" + implementation "org.springframework:spring-webmvc" + implementation "org.springframework.security:spring-security-config" + implementation "org.springframework.security:spring-security-web" + implementation "com.fasterxml.jackson.core:jackson-databind" + implementation "org.slf4j:slf4j-api" + implementation "org.slf4j:jcl-over-slf4j" + implementation "org.slf4j:log4j-over-slf4j" + implementation "ch.qos.logback:logback-classic" + implementation "org.testcontainers:testcontainers" + + providedCompile "jakarta.servlet:jakarta.servlet-api" + + testImplementation "org.springframework.security:spring-security-test" + testImplementation "org.assertj:assertj-core" + testImplementation "org.springframework:spring-test" + testImplementation "org.junit.jupiter:junit-jupiter-api" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine" +} + +gretty { + jvmArgs = ['-Dspring.profiles.active=embedded-redis'] + servletContainer = 'tomcat10' +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/rest/RestMockMvcTests.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/rest/RestMockMvcTests.java new file mode 100644 index 000000000..ef77c5e9d --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/rest/RestMockMvcTests.java @@ -0,0 +1,112 @@ +/* + * Copyright 2014-2022 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 + * + * https://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 rest; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.testcontainers.containers.GenericContainer; +import sample.SecurityConfig; +import sample.mvc.MvcConfig; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.session.Session; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; +import org.springframework.session.web.http.HeaderHttpSessionIdResolver; +import org.springframework.session.web.http.HttpSessionIdResolver; +import org.springframework.session.web.http.SessionRepositoryFilter; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { RestMockMvcTests.Config.class, SecurityConfig.class, MvcConfig.class }) +@WebAppConfiguration +class RestMockMvcTests { + + private static final String DOCKER_IMAGE = "redis:7.0.4-alpine"; + + @Autowired + private SessionRepositoryFilter sessionRepositoryFilter; + + @Autowired + private WebApplicationContext context; + + private MockMvc mvc; + + @BeforeEach + void setup() { + this.mvc = MockMvcBuilders.webAppContextSetup(this.context).alwaysDo(print()) + .addFilters(this.sessionRepositoryFilter).apply(springSecurity()).build(); + } + + @Test + void noSessionOnNoCredentials() throws Exception { + this.mvc.perform(get("/")).andExpect(header().doesNotExist("X-Auth-Token")) + .andExpect(status().isUnauthorized()); + } + + @WithMockUser + @Test + void autheticatedAnnotation() throws Exception { + this.mvc.perform(get("/")).andExpect(content().string("{\"username\":\"user\"}")); + } + + @Test + void autheticatedRequestPostProcessor() throws Exception { + this.mvc.perform(get("/").with(user("user"))).andExpect(content().string("{\"username\":\"user\"}")); + } + + @Configuration + @EnableRedisHttpSession + static class Config { + + @Bean + GenericContainer redisContainer() { + GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE).withExposedPorts(6379); + redisContainer.start(); + return redisContainer; + } + + @Bean + LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(redisContainer().getHost(), redisContainer().getFirstMappedPort()); + } + + @Bean + HttpSessionIdResolver httpSessionIdResolver() { + return HeaderHttpSessionIdResolver.xAuthToken(); + } + + } + +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/sample/RestTests.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/sample/RestTests.java new file mode 100644 index 000000000..ae1c9ca30 --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/sample/RestTests.java @@ -0,0 +1,125 @@ +/* + * Copyright 2014-2019 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 + * + * https://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.Base64; +import java.util.Collections; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * @author Pool Dolorier + */ +class RestTests { + + private static final String AUTHORIZATION = "Authorization"; + + private static final String BASIC = "Basic "; + + private static final String X_AUTH_TOKEN = "X-Auth-Token"; + + private RestTemplate restTemplate; + + private String baseUrl; + + @BeforeEach + void setUp() { + this.baseUrl = "http://localhost:" + System.getProperty("app.port"); + this.restTemplate = new RestTemplate(); + } + + @Test + void unauthenticatedUserSentToLogInPage() { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + assertThatExceptionOfType(HttpClientErrorException.class) + .isThrownBy(() -> getForUser(this.baseUrl + "/", headers, String.class)) + .satisfies((e) -> assertThat(e.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED)); + } + + @Test + void authenticateWithBasicWorks() { + String auth = getAuth("user", "password"); + HttpHeaders headers = getHttpHeaders(); + headers.set(AUTHORIZATION, BASIC + auth); + ResponseEntity entity = getForUser(this.baseUrl + "/", headers, User.class); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getHeaders().containsKey(X_AUTH_TOKEN)).isTrue(); + assertThat(entity.getBody().getUsername()).isEqualTo("user"); + } + + @Test + void authenticateWithXAuthTokenWorks() { + String auth = getAuth("user", "password"); + HttpHeaders headers = getHttpHeaders(); + headers.set(AUTHORIZATION, BASIC + auth); + ResponseEntity entity = getForUser(this.baseUrl + "/", headers, User.class); + + String token = entity.getHeaders().getFirst(X_AUTH_TOKEN); + + HttpHeaders authTokenHeader = new HttpHeaders(); + authTokenHeader.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + authTokenHeader.set(X_AUTH_TOKEN, token); + ResponseEntity authTokenResponse = getForUser(this.baseUrl + "/", authTokenHeader, User.class); + assertThat(authTokenResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(authTokenResponse.getBody().getUsername()).isEqualTo("user"); + } + + @Test + void logout() { + String auth = getAuth("user", "password"); + HttpHeaders headers = getHttpHeaders(); + headers.set(AUTHORIZATION, BASIC + auth); + ResponseEntity entity = getForUser(this.baseUrl + "/", headers, User.class); + + String token = entity.getHeaders().getFirst(X_AUTH_TOKEN); + + HttpHeaders logoutHeader = getHttpHeaders(); + logoutHeader.set(X_AUTH_TOKEN, token); + ResponseEntity logoutResponse = getForUser(this.baseUrl + "/logout", logoutHeader, User.class); + assertThat(logoutResponse.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); + } + + private ResponseEntity getForUser(String resourceUrl, HttpHeaders headers, Class type) { + return this.restTemplate.exchange(resourceUrl, HttpMethod.GET, new HttpEntity(headers), type); + } + + private HttpHeaders getHttpHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + return headers; + } + + private String getAuth(String user, String password) { + String auth = user + ":" + password; + return Base64.getEncoder().encodeToString(auth.getBytes()); + } + +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/sample/User.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/sample/User.java new file mode 100644 index 000000000..5c53924dc --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/integration-test/java/sample/User.java @@ -0,0 +1,34 @@ +/* + * Copyright 2014-2019 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 + * + * https://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 Pool Dolorier + */ +public class User { + + private String username; + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/EmbeddedRedisConfig.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/EmbeddedRedisConfig.java new file mode 100644 index 000000000..db12b562d --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/EmbeddedRedisConfig.java @@ -0,0 +1,46 @@ +/* + * Copyright 2014-2022 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 + * + * https://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.testcontainers.containers.GenericContainer; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; + +@Configuration +@Profile("embedded-redis") +public class EmbeddedRedisConfig { + + private static final String DOCKER_IMAGE = "redis:7.0.4-alpine"; + + @Bean + public GenericContainer redisContainer() { + GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE).withExposedPorts(6379); + redisContainer.start(); + return redisContainer; + } + + @Bean + @Primary + public LettuceConnectionFactory redisConnectionFactory() { + return new LettuceConnectionFactory(redisContainer().getHost(), redisContainer().getFirstMappedPort()); + } + +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/HttpSessionConfig.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/HttpSessionConfig.java new file mode 100644 index 000000000..490b4c59b --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/HttpSessionConfig.java @@ -0,0 +1,44 @@ +/* + * Copyright 2014-2019 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 + * + * https://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.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; +import org.springframework.session.web.http.HeaderHttpSessionIdResolver; +import org.springframework.session.web.http.HttpSessionIdResolver; + +@Import(EmbeddedRedisConfig.class) +// tag::class[] +@Configuration +@EnableRedisHttpSession // <1> +public class HttpSessionConfig { + + @Bean + public LettuceConnectionFactory connectionFactory() { + return new LettuceConnectionFactory(); // <2> + } + + @Bean + public HttpSessionIdResolver httpSessionIdResolver() { + return HeaderHttpSessionIdResolver.xAuthToken(); // <3> + } + +} +// end::class[] diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/Initializer.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/Initializer.java new file mode 100644 index 000000000..f793917d2 --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/Initializer.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014-2016 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 + * + * https://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.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; + +// tag::class[] +public class Initializer extends AbstractHttpSessionApplicationInitializer { + +} +// end::class[] diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/SecurityConfig.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/SecurityConfig.java new file mode 100644 index 000000000..c86ef1203 --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/SecurityConfig.java @@ -0,0 +1,58 @@ +/* + * Copyright 2014-2022 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 + * + * https://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.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.savedrequest.NullRequestCache; + +@Configuration(proxyBeanMethods = false) +@EnableWebSecurity +public class SecurityConfig { + + // @formatter:off + @Bean + SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + return http + .authorizeHttpRequests((authorize) -> authorize + .anyRequest().authenticated() + ) + .requestCache((requestCache) -> requestCache + .requestCache(new NullRequestCache()) + ) + .httpBasic(Customizer.withDefaults()) + .sessionManagement((sessionManagement) -> sessionManagement + .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)) + .build(); + } + // @formatter:on + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser(User.withUsername("user").password("{noop}password").roles("USER").build()); + } + +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/SecurityInitializer.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/SecurityInitializer.java new file mode 100644 index 000000000..ed15a002d --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/SecurityInitializer.java @@ -0,0 +1,26 @@ +/* + * Copyright 2014-2016 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 + * + * https://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.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; + +/** + * @author Rob Winch + */ +public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer { + +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/MvcConfig.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/MvcConfig.java new file mode 100644 index 000000000..7f69a440d --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/MvcConfig.java @@ -0,0 +1,31 @@ +/* + * Copyright 2014-2019 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 + * + * https://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.mvc; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +/** + * @author Rob Winch + */ +@Configuration +@EnableWebMvc +@ComponentScan +public class MvcConfig { + +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/MvcInitializer.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/MvcInitializer.java new file mode 100644 index 000000000..79dabcf49 --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/MvcInitializer.java @@ -0,0 +1,46 @@ +/* + * Copyright 2014-2019 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 + * + * https://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.mvc; + +import sample.HttpSessionConfig; +import sample.SecurityConfig; + +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +/** + * @author Rob Winch + */ +public class MvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + + // tag::config[] + @Override + protected Class[] getRootConfigClasses() { + return new Class[] { SecurityConfig.class, HttpSessionConfig.class }; + } + // end::config[] + + @Override + protected Class[] getServletConfigClasses() { + return new Class[] { MvcConfig.class }; + } + + @Override + protected String[] getServletMappings() { + return new String[] { "/" }; + } + +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/RestDemoController.java b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/RestDemoController.java new file mode 100644 index 000000000..38928fd79 --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/java/sample/mvc/RestDemoController.java @@ -0,0 +1,49 @@ +/* + * Copyright 2014-2019 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 + * + * https://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.mvc; + +import java.security.Principal; +import java.util.HashMap; +import java.util.Map; + +import jakarta.servlet.http.HttpSession; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Rob Winch + */ +@RestController +public class RestDemoController { + + @RequestMapping(value = "/", produces = "application/json") + public Map helloUser(Principal principal) { + HashMap result = new HashMap<>(); + result.put("username", principal.getName()); + return result; + } + + @RequestMapping("/logout") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void logout(HttpSession session) { + session.invalidate(); + } + +} diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/resources/logback.xml b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/resources/logback.xml new file mode 100644 index 000000000..20e902212 --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/resources/testcontainers.properties b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/resources/testcontainers.properties new file mode 100644 index 000000000..e3e834192 --- /dev/null +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/resources/testcontainers.properties @@ -0,0 +1 @@ +ryuk.container.timeout=120 diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/webapp/META-INF/MANIFEST.MF b/spring-session-samples/spring-session-sample-javaconfig-rest/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 000000000..e69de29bb From f8c1fdb25028b4006244af8dd8f9e4179f936655 Mon Sep 17 00:00:00 2001 From: Marcus Da Coregio Date: Thu, 6 Apr 2023 14:01:56 -0300 Subject: [PATCH 2/2] Fix javaconfig-rest sample dependency --- .../spring-session-sample-javaconfig-rest.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-session-samples/spring-session-sample-javaconfig-rest/spring-session-sample-javaconfig-rest.gradle b/spring-session-samples/spring-session-sample-javaconfig-rest/spring-session-sample-javaconfig-rest.gradle index e076ed32d..cd61ca755 100644 --- a/spring-session-samples/spring-session-sample-javaconfig-rest/spring-session-sample-javaconfig-rest.gradle +++ b/spring-session-samples/spring-session-sample-javaconfig-rest/spring-session-sample-javaconfig-rest.gradle @@ -16,7 +16,7 @@ dependencies { implementation "ch.qos.logback:logback-classic" implementation "org.testcontainers:testcontainers" - providedCompile "jakarta.servlet:jakarta.servlet-api" + providedCompile "jakarta.servlet:jakarta.servlet-api:6.0.0" testImplementation "org.springframework.security:spring-security-test" testImplementation "org.assertj:assertj-core"