From 8844871e2bd38f035f05a1808c404f368ab02661 Mon Sep 17 00:00:00 2001 From: maibin Date: Fri, 16 Dec 2016 10:14:48 +0100 Subject: [PATCH] @Async and SecurityContext (#872) * @Async and Spring Security * @Async with SecurityContext propagated * Spring and @Async * Simulated Annealing algorithm * Rebase * Rebase --- .../algorithms/SimulatedAnnealingTest.java | 13 +++++ .../baeldung/spring/SecurityJavaConfig.java | 33 ++++++++---- .../web/controller/AsyncController.java | 13 +++++ .../baeldung/web/service/AsyncService.java | 11 ++++ .../web/service/AsyncServiceImpl.java | 36 +++++++++++++ .../src/main/resources/webSecurityConfig.xml | 51 +++++++++++-------- 6 files changed, 126 insertions(+), 31 deletions(-) create mode 100644 core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java create mode 100644 spring-security-rest/src/main/java/org/baeldung/web/service/AsyncService.java create mode 100644 spring-security-rest/src/main/java/org/baeldung/web/service/AsyncServiceImpl.java diff --git a/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java b/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java new file mode 100644 index 0000000000..06b599dede --- /dev/null +++ b/core-java/src/test/java/com/baeldung/algorithms/SimulatedAnnealingTest.java @@ -0,0 +1,13 @@ +package com.baeldung.algorithms; + +import org.junit.Assert; +import org.junit.Test; + +public class SimulatedAnnealingTest { + + @Test + public void testSimulateAnnealing() { + Assert.assertTrue(SimulatedAnnealing.simulateAnnealing(10, 1000, 0.9) > 0); + } + +} diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java index 3302482f48..448968a6c8 100644 --- a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java +++ b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java @@ -1,8 +1,7 @@ package org.baeldung.spring; import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler; -import org.baeldung.security.RestAuthenticationEntryPoint; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.MethodInvokingFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -10,6 +9,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au 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.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; @Configuration @@ -17,11 +17,11 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa @ComponentScan("org.baeldung.security") public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { - @Autowired - private RestAuthenticationEntryPoint restAuthenticationEntryPoint; +// @Autowired +// private RestAuthenticationEntryPoint restAuthenticationEntryPoint; - @Autowired - private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler; +// @Autowired +// private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler; public SecurityJavaConfig() { super(); @@ -38,17 +38,21 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { protected void configure(final HttpSecurity http) throws Exception {// @formatter:off http .csrf().disable() + .authorizeRequests() + .and() .exceptionHandling() - .authenticationEntryPoint(restAuthenticationEntryPoint) +// .authenticationEntryPoint(restAuthenticationEntryPoint) .and() .authorizeRequests() .antMatchers("/api/csrfAttacker*").permitAll() .antMatchers("/api/customer/**").permitAll() .antMatchers("/api/foos/**").authenticated() + .antMatchers("/api/async/**").authenticated() .and() - .formLogin() - .successHandler(authenticationSuccessHandler) - .failureHandler(new SimpleUrlAuthenticationFailureHandler()) + .httpBasic() +// .and() +// .successHandler(authenticationSuccessHandler) +// .failureHandler(new SimpleUrlAuthenticationFailureHandler()) .and() .logout(); } // @formatter:on @@ -62,5 +66,14 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { public SimpleUrlAuthenticationFailureHandler myFailureHandler() { return new SimpleUrlAuthenticationFailureHandler(); } + + @Bean + public MethodInvokingFactoryBean methodInvokingFactoryBean() { + MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean(); + methodInvokingFactoryBean.setTargetClass(SecurityContextHolder.class); + methodInvokingFactoryBean.setTargetMethod("setStrategyName"); + methodInvokingFactoryBean.setArguments(new String[]{SecurityContextHolder.MODE_INHERITABLETHREADLOCAL}); + return methodInvokingFactoryBean; + } } \ No newline at end of file diff --git a/spring-security-rest/src/main/java/org/baeldung/web/controller/AsyncController.java b/spring-security-rest/src/main/java/org/baeldung/web/controller/AsyncController.java index bc59b4226a..9e78a62eed 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/controller/AsyncController.java +++ b/spring-security-rest/src/main/java/org/baeldung/web/controller/AsyncController.java @@ -2,13 +2,20 @@ package org.baeldung.web.controller; import java.util.concurrent.Callable; +import org.baeldung.web.service.AsyncService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; @Controller public class AsyncController { + + @Autowired + private AsyncService asyncService; @RequestMapping(method = RequestMethod.POST, value = "/upload") public Callable processUpload(final MultipartFile file) { @@ -20,5 +27,11 @@ public class AsyncController { } }; } + + @RequestMapping(method = RequestMethod.GET, value = "/async") + @ResponseBody + public Boolean checkIfContextPropagated() throws Exception{ + return asyncService.checkIfPrincipalPropagated().call() && asyncService.checkIfContextPropagated(SecurityContextHolder.getContext()); + } } diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncService.java b/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncService.java new file mode 100644 index 0000000000..b7cf2b9f0c --- /dev/null +++ b/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncService.java @@ -0,0 +1,11 @@ +package org.baeldung.web.service; + +import java.util.concurrent.Callable; + +public interface AsyncService { + + Callable checkIfPrincipalPropagated(); + + Boolean checkIfContextPropagated(Object context); + +} diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncServiceImpl.java b/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncServiceImpl.java new file mode 100644 index 0000000000..51f8c5157b --- /dev/null +++ b/spring-security-rest/src/main/java/org/baeldung/web/service/AsyncServiceImpl.java @@ -0,0 +1,36 @@ +package org.baeldung.web.service; + +import java.util.concurrent.Callable; + +import org.apache.log4j.Logger; +import org.springframework.scheduling.annotation.Async; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +@Service +public class AsyncServiceImpl implements AsyncService { + + private static final Logger log = Logger.getLogger(AsyncService.class); + + @Override + public Callable checkIfPrincipalPropagated() { + Object before = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + log.info("Before new thread: " + before); + return new Callable() { + public Boolean call() throws Exception { + Object after = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + log.info("New thread: " + after); + return before == after; + } + }; + } + + @Async + @Override + public Boolean checkIfContextPropagated(Object context) { + log.info("Before @Async: " + context); + log.info("Inside @Async: " + SecurityContextHolder.getContext()); + return context == SecurityContextHolder.getContext(); + } + +} diff --git a/spring-security-rest/src/main/resources/webSecurityConfig.xml b/spring-security-rest/src/main/resources/webSecurityConfig.xml index cf8357633c..4172fe036f 100644 --- a/spring-security-rest/src/main/resources/webSecurityConfig.xml +++ b/spring-security-rest/src/main/resources/webSecurityConfig.xml @@ -1,33 +1,42 @@ - + http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> - - + + - + - + - - + + - - + + - - - - - - - - + + + + + + + + + + \ No newline at end of file