Skip to content

Commit a0906bb

Browse files
authored
Merge pull request #42599 from Malandril/fix-augment-bug
Fix augmentors called multiple times for each identity provider
2 parents 4b1ae89 + 1609bee commit a0906bb

File tree

3 files changed

+64
-10
lines changed

3 files changed

+64
-10
lines changed

extensions/security/runtime/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
<artifactId>quarkus-junit5-internal</artifactId>
5050
<scope>test</scope>
5151
</dependency>
52+
<dependency>
53+
<groupId>org.mockito</groupId>
54+
<artifactId>mockito-core</artifactId>
55+
<scope>test</scope>
56+
</dependency>
5257
</dependencies>
5358

5459
<build>

extensions/security/runtime/src/main/java/io/quarkus/security/runtime/QuarkusIdentityProviderManagerImpl.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public Uni<SecurityIdentity> authenticate(AuthenticationRequest request) {
6464
if (providers.size() == 1) {
6565
return handleSingleProvider(providers.get(0), request);
6666
}
67-
return handleProvider(0, (List) providers, request);
67+
return handleProviders((List) providers, request);
6868
} catch (Throwable t) {
6969
return Uni.createFrom().failure(t);
7070
}
@@ -106,18 +106,30 @@ public SecurityIdentity authenticateBlocking(AuthenticationRequest request) {
106106
throw new IllegalArgumentException(
107107
"No IdentityProviders were registered to handle AuthenticationRequest " + request);
108108
}
109-
return (SecurityIdentity) handleProvider(0, (List) providers, request).await().indefinitely();
109+
return (SecurityIdentity) handleProviders((List) providers, request).await().indefinitely();
110110
}
111111

112-
private <T extends AuthenticationRequest> Uni<SecurityIdentity> handleProvider(int pos,
112+
private <T extends AuthenticationRequest> Uni<SecurityIdentity> handleProviders(
113113
List<IdentityProvider<T>> providers, T request) {
114+
return handleProvider(0, providers, request)
115+
.onItem()
116+
.transformToUni(new Function<SecurityIdentity, Uni<? extends SecurityIdentity>>() {
117+
@Override
118+
public Uni<? extends SecurityIdentity> apply(SecurityIdentity securityIdentity) {
119+
return handleIdentityFromProvider(0, securityIdentity, request.getAttributes());
120+
}
121+
});
122+
}
123+
124+
private <T extends AuthenticationRequest> Uni<SecurityIdentity> handleProvider(int pos, List<IdentityProvider<T>> providers,
125+
T request) {
114126
if (pos == providers.size()) {
115127
//we failed to authentication
116128
log.debug("Authentication failed as providers would authenticate the request");
117129
return Uni.createFrom().failure(new AuthenticationFailedException());
118130
}
119131
IdentityProvider<T> current = providers.get(pos);
120-
Uni<SecurityIdentity> cs = current.authenticate(request, blockingRequestContext)
132+
return current.authenticate(request, blockingRequestContext)
121133
.onItem().transformToUni(new Function<SecurityIdentity, Uni<? extends SecurityIdentity>>() {
122134
@Override
123135
public Uni<SecurityIdentity> apply(SecurityIdentity securityIdentity) {
@@ -127,12 +139,6 @@ public Uni<SecurityIdentity> apply(SecurityIdentity securityIdentity) {
127139
return handleProvider(pos + 1, providers, request);
128140
}
129141
});
130-
return cs.onItem().transformToUni(new Function<SecurityIdentity, Uni<? extends SecurityIdentity>>() {
131-
@Override
132-
public Uni<? extends SecurityIdentity> apply(SecurityIdentity securityIdentity) {
133-
return handleIdentityFromProvider(0, securityIdentity, request.getAttributes());
134-
}
135-
});
136142
}
137143

138144
private Uni<SecurityIdentity> handleIdentityFromProvider(int pos, SecurityIdentity identity,

extensions/security/runtime/src/test/java/io/quarkus/security/runtime/QuarkusIdentityProviderManagerImplTest.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package io.quarkus.security.runtime;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
import static org.mockito.ArgumentMatchers.any;
6+
import static org.mockito.Mockito.spy;
7+
import static org.mockito.Mockito.times;
8+
import static org.mockito.Mockito.verify;
49

510
import java.util.concurrent.Executors;
611

@@ -11,6 +16,7 @@
1116
import io.quarkus.security.identity.IdentityProvider;
1217
import io.quarkus.security.identity.IdentityProviderManager;
1318
import io.quarkus.security.identity.SecurityIdentity;
19+
import io.quarkus.security.identity.SecurityIdentityAugmentor;
1420
import io.quarkus.security.identity.request.BaseAuthenticationRequest;
1521
import io.smallrye.mutiny.Uni;
1622

@@ -32,6 +38,21 @@ void testIdentityProviderPriority() {
3238
assertEquals(new QuarkusPrincipal("Bob"), identity.getPrincipal());
3339
}
3440

41+
@Test
42+
void testIdentityProviderAugmentOnlyOnce() {
43+
TestSecurityAugmentor augmentor = spy(new TestSecurityAugmentor());
44+
IdentityProviderManager identityProviderManager = QuarkusIdentityProviderManagerImpl.builder()
45+
.addProvider(new TestIdentityProviderSystemFirstPriorityNoop())
46+
.addProvider(new TestIdentityProviderSystemLastPriorityUser())
47+
.addProvider(new AnonymousIdentityProvider())
48+
.addSecurityIdentityAugmentor(augmentor)
49+
.setBlockingExecutor(Executors.newSingleThreadExecutor()).build();
50+
SecurityIdentity identity = identityProviderManager.authenticateBlocking(new TestAuthenticationRequest());
51+
assertEquals(new QuarkusPrincipal("Bob"), identity.getPrincipal());
52+
assertTrue(identity.getRoles().contains("role"));
53+
verify(augmentor, times(1)).augment(any(), any());
54+
}
55+
3556
static class TestAuthenticationRequest extends BaseAuthenticationRequest {
3657
}
3758

@@ -78,4 +99,26 @@ public int priority() {
7899
return SYSTEM_LAST;
79100
}
80101
}
102+
103+
static class TestIdentityProviderSystemFirstPriorityNoop extends TestIdentityProviderSystemLastPriority {
104+
@Override
105+
public Uni<SecurityIdentity> authenticate(TestAuthenticationRequest request, AuthenticationRequestContext context) {
106+
return Uni.createFrom().nullItem();
107+
}
108+
}
109+
110+
static class TestIdentityProviderSystemLastPriorityUser extends TestIdentityProviderUserFirstPriority {
111+
@Override
112+
public int priority() {
113+
return SYSTEM_LAST;
114+
}
115+
}
116+
117+
private static class TestSecurityAugmentor implements SecurityIdentityAugmentor {
118+
@Override
119+
public Uni<SecurityIdentity> augment(SecurityIdentity securityIdentity,
120+
AuthenticationRequestContext authenticationRequestContext) {
121+
return Uni.createFrom().item(QuarkusSecurityIdentity.builder(securityIdentity).addRole("role").build());
122+
}
123+
}
81124
}

0 commit comments

Comments
 (0)