Propagate SecurityContext into @Transactional methods. (#1979)
Closes #1944.
This commit is contained in:
@@ -18,6 +18,7 @@ package org.springframework.data.couchbase.transactions;
|
||||
|
||||
import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS;
|
||||
|
||||
import org.springframework.data.couchbase.util.Util;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
@@ -119,6 +120,7 @@ public class CouchbasePersonTransactionReactiveIntegrationTests extends JavaInte
|
||||
@Test
|
||||
public void commitShouldPersistTxEntries() {
|
||||
|
||||
System.err.println("parent SecurityContext: " + System.identityHashCode(Util.getSecurityContext()));
|
||||
personService.savePerson(WalterWhite) //
|
||||
.as(StepVerifier::create) //
|
||||
.expectNextCount(1) //
|
||||
@@ -130,6 +132,17 @@ public class CouchbasePersonTransactionReactiveIntegrationTests extends JavaInte
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void commitShouldPersistTxEntriesBlocking() {
|
||||
System.err.println("parent SecurityContext: " + System.identityHashCode(Util.getSecurityContext()));
|
||||
Person p = personService.savePersonBlocking(WalterWhite);
|
||||
|
||||
operations.findByQuery(Person.class).withConsistency(REQUEST_PLUS).count() //
|
||||
.as(StepVerifier::create) //
|
||||
.expectNext(1L) //
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void commitShouldPersistTxEntriesOfTxAnnotatedMethod() {
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.springframework.data.couchbase.core.TransactionalSupport;
|
||||
import org.springframework.data.couchbase.domain.PersonWithoutVersion;
|
||||
import org.springframework.data.couchbase.transaction.CouchbaseResourceHolder;
|
||||
import org.springframework.data.couchbase.util.Util;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -31,6 +33,9 @@ import org.springframework.data.couchbase.domain.Person;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.reactive.TransactionalOperator;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* reactive PersonService for tests
|
||||
*
|
||||
@@ -57,8 +62,15 @@ class PersonServiceReactive {
|
||||
.<Person> flatMap(it -> Mono.error(new SimulateFailureException()));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Person savePersonBlocking(Person person) {
|
||||
System.err.println("savePerson: "+Thread.currentThread().getName() +" "+ System.identityHashCode(Util.getSecurityContext()));
|
||||
return personOperations.insertById(Person.class).one(person);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Mono<Person> savePerson(Person person) {
|
||||
System.err.println("savePerson: "+Thread.currentThread().getName() +" "+ System.identityHashCode(Util.getSecurityContext()));
|
||||
return TransactionalSupport.checkForTransactionInThreadLocalStorage().map(stat -> {
|
||||
assertTrue(stat.isPresent(), "Not in transaction");
|
||||
System.err.println("In a transaction!!");
|
||||
|
||||
@@ -20,6 +20,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.awaitility.Awaitility.with;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
@@ -170,4 +171,26 @@ public class Util {
|
||||
+ " but expected in-annotation-transaction = " + inTransaction);
|
||||
}
|
||||
|
||||
static public Object getSecurityContext(){
|
||||
Object sc = null;
|
||||
try {
|
||||
Class<?> securityContextHolderClass = Class
|
||||
.forName("org.springframework.security.core.context.SecurityContextHolder");
|
||||
sc = securityContextHolderClass.getMethod("getContext").invoke(null);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
|
||||
| InvocationTargetException cnfe) {}
|
||||
System.err.println(Thread.currentThread().getName() +" Util.get "+ System.identityHashCode(sc));
|
||||
return sc;
|
||||
}
|
||||
|
||||
static public void setSecurityContext(Object sc) {
|
||||
System.err.println(Thread.currentThread().getName() +" Util.set "+ System.identityHashCode(sc));
|
||||
try {
|
||||
Class<?> securityContextHolderClass = Class
|
||||
.forName("org.springframework.security.core.context.SecurityContextHolder");
|
||||
sc = securityContextHolderClass.getMethod("setContext", new Class[]{securityContextHolderClass}).invoke(sc);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
|
||||
| InvocationTargetException cnfe) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user