Skip to content

Commit

Permalink
Merge pull request quarkusio#13573 from stuartwdouglas/13559
Browse files Browse the repository at this point in the history
Fix potential hang if exception is thrown from authenticator
  • Loading branch information
sberyozkin authored Dec 3, 2020
2 parents 35ff0f9 + 368719c commit 38c4fe0
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,19 @@ public void run() {
* @return The first identity provider that was registered with this type
*/
public Uni<SecurityIdentity> authenticate(AuthenticationRequest request) {
List<IdentityProvider> providers = this.providers.get(request.getClass());
if (providers == null) {
return Uni.createFrom().failure(new IllegalArgumentException(
"No IdentityProviders were registered to handle AuthenticationRequest " + request));
}
if (providers.size() == 1) {
return handleSingleProvider(providers.get(0), request);
try {
List<IdentityProvider> providers = this.providers.get(request.getClass());
if (providers == null) {
return Uni.createFrom().failure(new IllegalArgumentException(
"No IdentityProviders were registered to handle AuthenticationRequest " + request));
}
if (providers.size() == 1) {
return handleSingleProvider(providers.get(0), request);
}
return handleProvider(0, (List) providers, request, blockingRequestContext);
} catch (Throwable t) {
return Uni.createFrom().failure(t);
}
return handleProvider(0, (List) providers, request, blockingRequestContext);
}

private Uni<SecurityIdentity> handleSingleProvider(IdentityProvider identityProvider, AuthenticationRequest request) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.quarkus.vertx.http.security;

import java.util.function.Supplier;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;

public class FailedIdentityProviderTestCase {

private static final String APP_PROPS = "" +
"quarkus.http.auth.basic=true\n" +
"quarkus.http.auth.policy.r1.roles-allowed=admin\n" +
"quarkus.http.auth.permission.roles1.paths=/admin\n" +
"quarkus.http.auth.permission.roles1.policy=r1\n";

@RegisterExtension
static QuarkusUnitTest test = new QuarkusUnitTest().setArchiveProducer(new Supplier<JavaArchive>() {
@Override
public JavaArchive get() {
return ShrinkWrap.create(JavaArchive.class)
.addClasses(FailingIdentityProvider.class,
PathHandler.class)
.addAsResource(new StringAsset(APP_PROPS), "application.properties");
}
});

@Test
public void testBasicBasedAuthSuccess() {
RestAssured
.given()
.auth().preemptive().basic("admin", "admin")
.redirects().follow(false)
.when()
.get("/admin")
.then()
.assertThat()
.statusCode(401);

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.vertx.http.security;

import javax.inject.Singleton;

import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.IdentityProvider;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest;
import io.smallrye.mutiny.Uni;

@Singleton
public class FailingIdentityProvider implements IdentityProvider<UsernamePasswordAuthenticationRequest> {
@Override
public Class<UsernamePasswordAuthenticationRequest> getRequestType() {
return UsernamePasswordAuthenticationRequest.class;
}

@Override
public Uni<SecurityIdentity> authenticate(UsernamePasswordAuthenticationRequest request,
AuthenticationRequestContext context) {
throw new AuthenticationFailedException("FAILED");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ public void accept(Throwable throwable) {
return;
}
if (event.failure() instanceof AuthenticationFailedException) {
return; //handled elsewhere
//generally this should be handled elsewhere
//but if we get to this point bad things have happened
//so it is better to send a response than to hang
event.response().setStatusCode(HttpResponseStatus.UNAUTHORIZED.code()).end();
return;
}

if (!event.response().headWritten()) {
Expand Down

0 comments on commit 38c4fe0

Please sign in to comment.