This commit is contained in:
Adam InTae Gerard 2018-10-19 21:29:05 -07:00 committed by Grzegorz Piwowarek
parent 7d7cae7b0b
commit 2404312d20
9 changed files with 226 additions and 0 deletions

View File

@ -14,3 +14,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Spring Webflux and CORS](http://www.baeldung.com/spring-webflux-cors)
- [Handling Errors in Spring WebFlux](http://www.baeldung.com/spring-webflux-errors)
- [Server-Sent Events in Spring](https://www.baeldung.com/spring-server-sent-events)
- [A Guide to Spring Session Reactive Support: WebSession](https://www.baeldung.com/a-guide-to-spring-session-reactive-support-websession/)

View File

@ -76,6 +76,28 @@
<scope>test</scope>
</dependency>
<!-- Spring WebFlux WebSession -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>

View File

@ -0,0 +1,15 @@
package com.baeldung.websession;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"com.baeldung"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.websession.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession;
@Configuration
//@EnableRedisWebSession
public class RedisConfig {
/**
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}
*/
}

View File

@ -0,0 +1,20 @@
package com.baeldung.websession.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.ReactiveMapSessionRepository;
import org.springframework.session.ReactiveSessionRepository;
import org.springframework.session.config.annotation.web.server.EnableSpringWebSession;
import java.util.concurrent.ConcurrentHashMap;
@Configuration
@EnableSpringWebSession
public class SessionConfig {
@Bean
public ReactiveSessionRepository reactiveSessionRepository() {
return new ReactiveMapSessionRepository(new ConcurrentHashMap<>());
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.websession.configuration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
@Configuration
@EnableWebFlux
public class WebFluxConfig implements ApplicationContextAware, WebFluxConfigurer {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) {
this.context = context;
}
}

View File

@ -0,0 +1,58 @@
package com.baeldung.websession.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
@Configuration
@EnableWebFluxSecurity
public class WebFluxSecurityConfig {
@Bean
public MapReactiveUserDetailsService userDetailsService() {
UserDetails admin = User
.withUsername("admin")
.password(encoder().encode("password"))
.roles("ADMIN")
.build();
UserDetails user = User
.withUsername("user")
.password(encoder().encode("password"))
.roles("USER")
.build();
return new MapReactiveUserDetailsService(admin, user);
}
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.httpBasic()
.securityContextRepository(new WebSessionServerSecurityContextRepository())
.and()
.formLogin();
http
.csrf().disable();
return http.build();
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.websession.controller;
import com.baeldung.websession.transfer.CustomResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.WebSession;
import reactor.core.publisher.Mono;
@RestController
public class SessionController {
@GetMapping("/websession/test")
public Mono<CustomResponse> testWebSessionByParam(
@RequestParam(value = "id") int id,
@RequestParam(value = "note") String note,
WebSession session) {
session.getAttributes().put("id", id);
session.getAttributes().put("note", note);
CustomResponse r = new CustomResponse();
r.setId((int) session.getAttributes().get("id"));
r.setNote((String) session.getAttributes().get("note"));
return Mono.just(r);
}
@GetMapping("/websession")
public Mono<CustomResponse> getSession(WebSession session) {
session.getAttributes().putIfAbsent("id", 0);
session.getAttributes().putIfAbsent("note", "Howdy Cosmic Spheroid!");
CustomResponse r = new CustomResponse();
r.setId((int) session.getAttributes().get("id"));
r.setNote((String) session.getAttributes().get("note"));
return Mono.just(r);
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.websession.transfer;
public class CustomResponse {
private int id;
private String note;
public CustomResponse() {}
public CustomResponse(int id, String note) {
this.id = id;
this.note = note;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}