@Async and SecurityContext (#872)
* @Async and Spring Security * @Async with SecurityContext propagated * Spring and @Async * Simulated Annealing algorithm * Rebase * Rebase
This commit is contained in:
parent
0087a4ab3b
commit
8844871e2b
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
package org.baeldung.spring;
|
package org.baeldung.spring;
|
||||||
|
|
||||||
import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler;
|
import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler;
|
||||||
import org.baeldung.security.RestAuthenticationEntryPoint;
|
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
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.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@ -17,11 +17,11 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
|
||||||
@ComponentScan("org.baeldung.security")
|
@ComponentScan("org.baeldung.security")
|
||||||
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
|
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Autowired
|
// @Autowired
|
||||||
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
|
// private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
|
||||||
|
|
||||||
@Autowired
|
// @Autowired
|
||||||
private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler;
|
// private MySavedRequestAwareAuthenticationSuccessHandler authenticationSuccessHandler;
|
||||||
|
|
||||||
public SecurityJavaConfig() {
|
public SecurityJavaConfig() {
|
||||||
super();
|
super();
|
||||||
|
@ -38,17 +38,21 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
|
||||||
protected void configure(final HttpSecurity http) throws Exception {// @formatter:off
|
protected void configure(final HttpSecurity http) throws Exception {// @formatter:off
|
||||||
http
|
http
|
||||||
.csrf().disable()
|
.csrf().disable()
|
||||||
|
.authorizeRequests()
|
||||||
|
.and()
|
||||||
.exceptionHandling()
|
.exceptionHandling()
|
||||||
.authenticationEntryPoint(restAuthenticationEntryPoint)
|
// .authenticationEntryPoint(restAuthenticationEntryPoint)
|
||||||
.and()
|
.and()
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.antMatchers("/api/csrfAttacker*").permitAll()
|
.antMatchers("/api/csrfAttacker*").permitAll()
|
||||||
.antMatchers("/api/customer/**").permitAll()
|
.antMatchers("/api/customer/**").permitAll()
|
||||||
.antMatchers("/api/foos/**").authenticated()
|
.antMatchers("/api/foos/**").authenticated()
|
||||||
|
.antMatchers("/api/async/**").authenticated()
|
||||||
.and()
|
.and()
|
||||||
.formLogin()
|
.httpBasic()
|
||||||
.successHandler(authenticationSuccessHandler)
|
// .and()
|
||||||
.failureHandler(new SimpleUrlAuthenticationFailureHandler())
|
// .successHandler(authenticationSuccessHandler)
|
||||||
|
// .failureHandler(new SimpleUrlAuthenticationFailureHandler())
|
||||||
.and()
|
.and()
|
||||||
.logout();
|
.logout();
|
||||||
} // @formatter:on
|
} // @formatter:on
|
||||||
|
@ -63,4 +67,13 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
|
||||||
return new SimpleUrlAuthenticationFailureHandler();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,14 +2,21 @@ package org.baeldung.web.controller;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
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.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class AsyncController {
|
public class AsyncController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AsyncService asyncService;
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = "/upload")
|
@RequestMapping(method = RequestMethod.POST, value = "/upload")
|
||||||
public Callable<Boolean> processUpload(final MultipartFile file) {
|
public Callable<Boolean> processUpload(final MultipartFile file) {
|
||||||
|
|
||||||
|
@ -21,4 +28,10 @@ public class AsyncController {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/async")
|
||||||
|
@ResponseBody
|
||||||
|
public Boolean checkIfContextPropagated() throws Exception{
|
||||||
|
return asyncService.checkIfPrincipalPropagated().call() && asyncService.checkIfContextPropagated(SecurityContextHolder.getContext());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package org.baeldung.web.service;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public interface AsyncService {
|
||||||
|
|
||||||
|
Callable<Boolean> checkIfPrincipalPropagated();
|
||||||
|
|
||||||
|
Boolean checkIfContextPropagated(Object context);
|
||||||
|
|
||||||
|
}
|
|
@ -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<Boolean> checkIfPrincipalPropagated() {
|
||||||
|
Object before = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
|
log.info("Before new thread: " + before);
|
||||||
|
return new Callable<Boolean>() {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,33 +1,42 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
<beans:beans xmlns="http://www.springframework.org/schema/security"
|
||||||
xmlns:sec="http://www.springframework.org/schema/security"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||||
xsi:schemaLocation="
|
xmlns:sec="http://www.springframework.org/schema/security"
|
||||||
|
xmlns:p="http://www.springframework.org/schema/p"
|
||||||
|
xsi:schemaLocation="
|
||||||
http://www.springframework.org/schema/security
|
http://www.springframework.org/schema/security
|
||||||
http://www.springframework.org/schema/security/spring-security-4.2.xsd
|
http://www.springframework.org/schema/security/spring-security-4.2.xsd
|
||||||
http://www.springframework.org/schema/beans
|
http://www.springframework.org/schema/beans
|
||||||
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"
|
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
|
||||||
>
|
|
||||||
|
|
||||||
<http use-expressions="true" entry-point-ref="restAuthenticationEntryPoint">
|
<http use-expressions="true" entry-point-ref="restAuthenticationEntryPoint">
|
||||||
<intercept-url pattern="/api/**" access="isAuthenticated()"/>
|
<intercept-url pattern="/api/**" access="isAuthenticated()" />
|
||||||
|
|
||||||
<csrf disabled="true"/>
|
<csrf disabled="true" />
|
||||||
|
|
||||||
<form-login authentication-success-handler-ref="mySuccessHandler" authentication-failure-handler-ref="myFailureHandler"/>
|
<form-login authentication-success-handler-ref="mySuccessHandler"
|
||||||
|
authentication-failure-handler-ref="myFailureHandler" />
|
||||||
|
|
||||||
<logout/>
|
<logout />
|
||||||
</http>
|
</http>
|
||||||
|
|
||||||
<beans:bean id="mySuccessHandler" class="org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler"/>
|
<beans:bean id="mySuccessHandler"
|
||||||
<beans:bean id="myFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"/>
|
class="org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler" />
|
||||||
|
<beans:bean id="myFailureHandler"
|
||||||
|
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" />
|
||||||
|
|
||||||
<authentication-manager alias="authenticationManager">
|
<authentication-manager alias="authenticationManager">
|
||||||
<authentication-provider>
|
<authentication-provider>
|
||||||
<user-service>
|
<user-service>
|
||||||
<user name="temporary" password="temporary" authorities="ROLE_ADMIN"/>
|
<user name="temporary" password="temporary" authorities="ROLE_ADMIN" />
|
||||||
<user name="user" password="userPass" authorities="ROLE_USER"/>
|
<user name="user" password="userPass" authorities="ROLE_USER" />
|
||||||
</user-service>
|
</user-service>
|
||||||
</authentication-provider>
|
</authentication-provider>
|
||||||
</authentication-manager>
|
</authentication-manager>
|
||||||
|
|
||||||
|
<beans:bean
|
||||||
|
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
|
||||||
|
p:targetClass="org.springframework.security.core.context.SecurityContextHolder"
|
||||||
|
p:targetMethod="setStrategyName" p:arguments="MODE_INHERITABLETHREADLOCAL" />
|
||||||
|
|
||||||
</beans:beans>
|
</beans:beans>
|
Loading…
Reference in New Issue