diff --git a/spring-cloud/spring-cloud-bootstrap/application-config/discovery.properties b/spring-cloud/spring-cloud-bootstrap/application-config/discovery.properties
index dd117e128c..46f475208b 100644
--- a/spring-cloud/spring-cloud-bootstrap/application-config/discovery.properties
+++ b/spring-cloud/spring-cloud-bootstrap/application-config/discovery.properties
@@ -6,3 +6,6 @@ eureka.instance.hostname=localhost
eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
+
+spring.redis.host=localhost
+spring.redis.port=6379
diff --git a/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties b/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties
index b33f28f7a6..c2a9419fc8 100644
--- a/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties
+++ b/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties
@@ -5,5 +5,9 @@ eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5
zuul.routes.resource.path=/resource/**
+zuul.routes.resource.sensitiveHeaders=Set-Cookie,Authorization,Cookie
hystrix.command.resource.execution.isolation.thread.timeoutInMilliseconds: 5000
+spring.redis.host=localhost
+spring.redis.port=6379
+
diff --git a/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties b/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties
index e19715e986..6cd94c59e3 100644
--- a/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties
+++ b/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties
@@ -2,6 +2,11 @@ spring.application.name=resource
server.port=8083
resource.returnString=hello cloud
+resource.user.returnString=hello cloud user
+resource.admin.returnString=hello cloud admin
eureka.client.region = default
eureka.client.registryFetchIntervalSeconds = 5
+
+spring.redis.host=localhost
+spring.redis.port=6379
diff --git a/spring-cloud/spring-cloud-bootstrap/config/pom.xml b/spring-cloud/spring-cloud-bootstrap/config/pom.xml
index 9ba018733a..bcb40ac062 100644
--- a/spring-cloud/spring-cloud-bootstrap/config/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/config/pom.xml
@@ -52,6 +52,15 @@
org.springframework.boot
spring-boot-maven-plugin
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+ 1.8
+ 1.8
+
+
diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml b/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml
index 3b23adbf54..f3cb3be2af 100644
--- a/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml
@@ -32,6 +32,16 @@
org.springframework.boot
spring-boot-starter-security
+
+
+ org.springframework.session
+ spring-session
+ 1.2.1.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
@@ -52,6 +62,15 @@
org.springframework.boot
spring-boot-maven-plugin
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+ 1.8
+ 1.8
+
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SecurityConfig.java
index 22e0369cb1..780d20e573 100644
--- a/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SecurityConfig.java
+++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SecurityConfig.java
@@ -17,11 +17,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
auth.inMemoryAuthentication()
.withUser("discUser")
.password("discPassword")
- .roles("SYSTEM")
- .and()
- .withUser("admin")
- .password("password")
- .roles("ADMIN");
+ .roles("SYSTEM");
}
@Override
diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SessionConfig.java b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SessionConfig.java
new file mode 100644
index 0000000000..83e5f51c97
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/bootstrap/discovery/SessionConfig.java
@@ -0,0 +1,8 @@
+package com.baeldung.spring.cloud.bootstrap.discovery;
+
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
+
+@EnableRedisHttpSession
+public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml
index 8e56d0fd35..add551ff95 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml
@@ -27,6 +27,21 @@
org.springframework.cloud
spring-cloud-starter-zuul
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ org.springframework.session
+ spring-session
+ 1.2.1.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
org.springframework.boot
spring-boot-starter-test
@@ -52,6 +67,15 @@
org.springframework.boot
spring-boot-maven-plugin
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+ 1.8
+ 1.8
+
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/CustomAuthenticationHandler.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/CustomAuthenticationHandler.java
new file mode 100644
index 0000000000..13c993ff35
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/CustomAuthenticationHandler.java
@@ -0,0 +1,54 @@
+package com.baeldung.spring.cloud.bootstrap.gateway;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.WebAttributes;
+import org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler;
+import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+public class CustomAuthenticationHandler extends AbstractAuthenticationTargetUrlRequestHandler implements AuthenticationSuccessHandler{
+
+ public CustomAuthenticationHandler() {
+ }
+
+ /**
+ * Constructor which sets the defaultTargetUrl property of the base class.
+ * @param defaultTargetUrl the URL to which the user should be redirected on
+ * successful authentication.
+ */
+ public CustomAuthenticationHandler(String defaultTargetUrl) {
+ setDefaultTargetUrl(defaultTargetUrl);
+ }
+
+ /**
+ * Calls the parent class {@code handle()} method to forward or redirect to the target
+ * URL, and then calls {@code clearAuthenticationAttributes()} to remove any leftover
+ * session data.
+ */
+ public void onAuthenticationSuccess(HttpServletRequest request,
+ HttpServletResponse response, Authentication authentication)
+ throws IOException, ServletException {
+ response.setStatus(303);
+ handle(request, response, authentication);
+ clearAuthenticationAttributes(request);
+ }
+
+ /**
+ * Removes temporary authentication-related data which may have been stored in the
+ * session during the authentication process.
+ */
+ protected final void clearAuthenticationAttributes(HttpServletRequest request) {
+ HttpSession session = request.getSession(false);
+
+ if (session == null) {
+ return;
+ }
+
+ session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java
index ecdd5e066f..a3d2df5357 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplication.java
@@ -1,9 +1,18 @@
package com.baeldung.spring.cloud.bootstrap.gateway;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+import org.springframework.cloud.netflix.ribbon.RibbonClientSpecification;
+import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
@SpringBootApplication
@EnableZuulProxy
@@ -12,4 +21,20 @@ public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
+
+ @Autowired(required = false)
+ private List configurations = new ArrayList<>();
+
+ @Bean
+ @LoadBalanced RestTemplate restTemplate(){
+ return new RestTemplate();
+ }
+
+
+ @Bean
+ public SpringClientFactory springClientFactory() {
+ SpringClientFactory factory = new SpringClientFactory();
+ factory.setConfigurations(this.configurations);
+ return factory;
+ }
}
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java
new file mode 100644
index 0000000000..80ffcb019b
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java
@@ -0,0 +1,37 @@
+package com.baeldung.spring.cloud.bootstrap.gateway;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+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.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@EnableWebSecurity
+@Configuration
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Autowired
+ public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+ auth.inMemoryAuthentication()
+ .withUser("user").password("password").roles("USER")
+ .and()
+ .withUser("admin").password("admin").roles("ADMIN");
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .authorizeRequests()
+ .antMatchers("/resource/hello/cloud").permitAll()
+ .anyRequest().authenticated()
+ .and()
+ .formLogin()
+ .successHandler(new CustomAuthenticationHandler("/resource/hello/user"))
+ .and()
+ .logout().permitAll()
+ .logoutSuccessUrl("/resource/hello/cloud").permitAll()
+ .and()
+ .csrf().disable();
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SessionConfig.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SessionConfig.java
new file mode 100644
index 0000000000..14f7deb770
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SessionConfig.java
@@ -0,0 +1,11 @@
+package com.baeldung.spring.cloud.bootstrap.gateway;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.session.data.redis.RedisFlushMode;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
+
+@Configuration
+@EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE)
+public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SessionSavingZuulPreFilter.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SessionSavingZuulPreFilter.java
new file mode 100644
index 0000000000..a1eecaa7a0
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SessionSavingZuulPreFilter.java
@@ -0,0 +1,47 @@
+package com.baeldung.spring.cloud.bootstrap.gateway;
+
+import com.netflix.zuul.ZuulFilter;
+import com.netflix.zuul.context.RequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.session.Session;
+import org.springframework.session.SessionRepository;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpSession;
+
+@Component
+public class SessionSavingZuulPreFilter extends ZuulFilter {
+
+ private Logger log = LoggerFactory.getLogger(this.getClass());
+
+ @Autowired
+ private SessionRepository repository;
+
+ @Override public boolean shouldFilter() {
+ return true;
+ }
+
+ @Override
+ public Object run() {
+ RequestContext context = RequestContext.getCurrentContext();
+
+ HttpSession httpSession = context.getRequest().getSession();
+ Session session = repository.getSession(httpSession.getId());
+
+ context.addZuulRequestHeader("Cookie", "SESSION=" + httpSession.getId());
+
+ log.info("ZuulPreFilter session proxy: {}", session.getId());
+
+ return null;
+ }
+
+ @Override public String filterType() {
+ return "pre";
+ }
+
+ @Override public int filterOrder() {
+ return 0;
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/bootstrap.properties
index 43491ff36b..53101d1c57 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/bootstrap.properties
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/bootstrap.properties
@@ -4,4 +4,15 @@ spring.cloud.config.discovery.enabled=true
spring.cloud.config.username=configUser
spring.cloud.config.password=configPassword
-eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/
\ No newline at end of file
+eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/
+
+management.security.sessions=always
+
+zuul.routes.resource.path=/resource/**
+zuul.routes.resource.sensitive-headers=Set-Cookie,Authorization
+zuul.routes.resource.retryable=true
+hystrix.command.resource.execution.isolation.thread.timeoutInMilliseconds=600000
+
+logging.level.org.springframework.web.=debug
+logging.level.org.springframework.security=debug
+logging.level.org.springframework.cloud.netflix.zuul=debug
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/pom.xml b/spring-cloud/spring-cloud-bootstrap/resource/pom.xml
index 78112fa3e0..8940ca71da 100644
--- a/spring-cloud/spring-cloud-bootstrap/resource/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/resource/pom.xml
@@ -27,6 +27,21 @@
org.springframework.boot
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ org.springframework.session
+ spring-session
+ 1.2.1.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
org.springframework.boot
spring-boot-starter-test
@@ -52,6 +67,15 @@
org.springframework.boot
spring-boot-maven-plugin
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+ 1.8
+ 1.8
+
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/ResourceApplication.java b/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/ResourceApplication.java
index c567f67444..e12d43f46b 100644
--- a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/ResourceApplication.java
+++ b/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/ResourceApplication.java
@@ -18,8 +18,24 @@ public class ResourceApplication {
@Value("${resource.returnString}")
private String returnString;
+ @Value("${resource.user.returnString}")
+ private String userReturnString;
+
+ @Value("${resource.admin.returnString}")
+ private String adminReturnString;
+
@RequestMapping("/hello/cloud")
public String getString() {
return returnString;
}
+
+ @RequestMapping("/hello/user")
+ public String getUserString() {
+ return userReturnString;
+ }
+
+ @RequestMapping("/hello/admin")
+ public String getAdminString() {
+ return adminReturnString;
+ }
}
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SecurityConfig.java
new file mode 100644
index 0000000000..7351316e71
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SecurityConfig.java
@@ -0,0 +1,40 @@
+package com.baeldung.spring.cloud.bootstrap.resource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+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.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+@EnableWebSecurity
+@Configuration
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Autowired
+ public void configureGlobal1(AuthenticationManagerBuilder auth) throws Exception {
+ //try in memory auth with no users to support the case that this will allow for users that are logged in to go anywhere
+ auth.inMemoryAuthentication();
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .httpBasic()
+ .disable()
+ .authorizeRequests()
+ .antMatchers("/hello/cloud").permitAll()
+ .antMatchers("/hello/user").hasAnyRole("USER", "ADMIN")
+ .antMatchers("/hello/admin").hasAnyRole("ADMIN")
+ .anyRequest().authenticated()
+ .and()
+ .csrf().disable();
+ }
+
+ @Bean
+ public BCryptPasswordEncoder encoder() {
+ return new BCryptPasswordEncoder(11);
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SessionConfig.java b/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SessionConfig.java
new file mode 100644
index 0000000000..f11f316826
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SessionConfig.java
@@ -0,0 +1,10 @@
+package com.baeldung.spring.cloud.bootstrap.resource;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
+
+@Configuration
+@EnableRedisHttpSession
+public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/resource/src/main/resources/bootstrap.properties
index f915426a36..dd9e34b0a5 100644
--- a/spring-cloud/spring-cloud-bootstrap/resource/src/main/resources/bootstrap.properties
+++ b/spring-cloud/spring-cloud-bootstrap/resource/src/main/resources/bootstrap.properties
@@ -4,4 +4,9 @@ spring.cloud.config.discovery.enabled=true
spring.cloud.config.username=configUser
spring.cloud.config.password=configPassword
-eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/
\ No newline at end of file
+eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/
+
+management.security.sessions=never
+
+logging.level.org.springframework.web.=debug
+logging.level.org.springframework.security=debug
\ No newline at end of file