use of io.vertx.ext.auth.authentication.Credentials in project vertx-web by vert-x3.
the class CustomAuthHandlerTest method testCredentialsValidationErrorPropagation.
@SuppressWarnings("unchecked")
@Test
public void testCredentialsValidationErrorPropagation() throws Exception {
Handler<RoutingContext> handler = rc -> {
fail("should not get here");
rc.response().end("Welcome to the protected resource!");
};
Throwable rootCause = new IllegalArgumentException("validation of credentials failed");
AuthenticationProvider authProvider = mock(AuthenticationProvider.class);
doAnswer(invocation -> {
final Handler<AsyncResult<User>> resultHandler = invocation.getArgument(1);
resultHandler.handle(Future.failedFuture(rootCause));
return null;
}).when(authProvider).authenticate(any(Credentials.class), any(Handler.class));
router.route("/protected/*").handler(newAuthHandler(authProvider, exception -> {
assertTrue(exception instanceof IllegalArgumentException);
assertEquals(rootCause, exception);
}));
router.route("/protected/somepage").handler(handler);
testRequest(HttpMethod.GET, "/protected/somepage", 401, "Unauthorized");
}
use of io.vertx.ext.auth.authentication.Credentials in project vertx-web by vert-x3.
the class OAuth2AuthHandlerImpl method authenticate.
@Override
public void authenticate(RoutingContext context, Handler<AsyncResult<User>> handler) {
// when the handler is working as bearer only, then the `Authorization` header is required
parseAuthorization(context, !bearerOnly, parseAuthorization -> {
if (parseAuthorization.failed()) {
handler.handle(Future.failedFuture(parseAuthorization.cause()));
return;
}
// Authorization header can be null when in not in bearerOnly mode
final String token = parseAuthorization.result();
if (token == null) {
// redirect request to the oauth2 server as we know nothing about this request
if (bearerOnly) {
// it's a failure both cases but the cause is not the same
handler.handle(Future.failedFuture("callback route is not configured."));
return;
}
// an infinite redirect loop. In this case an exception must be raised.
if (context.request().method() == HttpMethod.GET && context.normalizedPath().equals(callbackURL.resource())) {
LOG.warn("The callback route is shaded by the OAuth2AuthHandler, ensure the callback route is added BEFORE the OAuth2AuthHandler route!");
handler.handle(Future.failedFuture(new HttpException(500, "Infinite redirect loop [oauth2 callback]")));
} else {
if (context.request().method() != HttpMethod.GET) {
// we can only redirect GET requests
LOG.error("OAuth2 redirect attempt to non GET resource");
context.fail(405, new IllegalStateException("OAuth2 redirect attempt to non GET resource"));
return;
}
// the redirect is processed as a failure to abort the chain
String redirectUri = context.request().uri();
String state = null;
String codeVerifier = null;
final Session session = context.session();
if (session == null) {
if (pkce > 0) {
// we can only handle PKCE with a session
context.fail(500, new IllegalStateException("OAuth2 PKCE requires a session to be present"));
return;
}
} else {
// there's a session we can make this request comply to the Oauth2 spec and add an opaque state
session.put("redirect_uri", context.request().uri());
// create a state value to mitigate replay attacks
state = prng.nextString(6);
// store the state in the session
session.put("state", state);
if (pkce > 0) {
codeVerifier = prng.nextString(pkce);
// store the code verifier in the session
session.put("pkce", codeVerifier);
}
}
handler.handle(Future.failedFuture(new HttpException(302, authURI(redirectUri, state, codeVerifier))));
}
} else {
// continue
final Credentials credentials = scopes.size() > 0 ? new TokenCredentials(token).setScopes(scopes) : new TokenCredentials(token);
authProvider.authenticate(credentials, authn -> {
if (authn.failed()) {
handler.handle(Future.failedFuture(new HttpException(401, authn.cause())));
} else {
handler.handle(authn);
}
});
}
});
}
Aggregations