BAEL-315 Adding spring session as mechanism for sharing authentication tokens created by the edge service.

This commit is contained in:
Tim Schimandle
2016-10-18 18:44:43 -06:00
parent a310184efa
commit 2a7b598cf0
19 changed files with 355 additions and 7 deletions
@@ -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 <tt>defaultTargetUrl</tt> 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);
}
}
@@ -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<RibbonClientSpecification> configurations = new ArrayList<>();
@Bean
@LoadBalanced RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean
public SpringClientFactory springClientFactory() {
SpringClientFactory factory = new SpringClientFactory();
factory.setConfigurations(this.configurations);
return factory;
}
}
@@ -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();
}
}
@@ -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 {
}
@@ -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;
}
}
@@ -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/
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