package org.pac4j.vertx; import io.vertx.core.buffer.Buffer; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.Router; import org.apache.commons.codec.binary.Base64; import org.junit.Test; import org.pac4j.core.client.Client; import org.pac4j.core.client.Clients; import org.pac4j.core.config.Config; import org.pac4j.core.matching.ExcludedPathMatcher; import org.pac4j.http.client.direct.DirectBasicAuthClient; import org.pac4j.http.credentials.authenticator.test.SimpleTestUsernamePasswordAuthenticator; import org.pac4j.vertx.auth.Pac4jAuthProvider; import org.pac4j.vertx.handler.impl.SecurityHandler; import org.pac4j.vertx.handler.impl.SecurityHandlerOptions; import java.util.ArrayList; import java.util.Optional; import java.util.function.Consumer; import static org.hamcrest.CoreMatchers.is; import static org.pac4j.vertx.TestConstants.UNAUTHORIZED_BODY; /** * @author Jeremy Prime * @since 2.0.0 */ public class StatelessPac4jAuthHandlerIntegrationTest extends StatelessPac4jAuthHandlerIntegrationTestBase { private static final String BASIC_AUTH_PREFIX = "Basic "; private static final String TEST_USER_NAME = "testUser"; private static final String TEST_BASIC_AUTH_HEADER = BASIC_AUTH_PREFIX + Base64.encodeBase64String((TEST_USER_NAME + ":testUser").getBytes()); private static final String TEST_FAILING_BASIC_AUTH_HEADER = BASIC_AUTH_PREFIX + Base64.encodeBase64String((TEST_USER_NAME + ":testUser2").getBytes()); private static final String BASIC_AUTH_CLIENT = "BasicAuthClient"; private static final String USERNAME_FIELD = "username"; private static final String EXCLUDED_PATH_MATCHER_NAME = "ExcludedPathMatcher"; @Test public void testSuccessfulLogin() throws Exception { testProtectedResourceAccessWithAuthHeader(TEST_BASIC_AUTH_HEADER, 200, validateJsonBody(this::validateProtectedResourceContent)); } @Test public void testFailedLogin() throws Exception { testProtectedResourceAccessWithAuthHeader(TEST_FAILING_BASIC_AUTH_HEADER, 401, unauthorizedContentValidator()); } @Test public void testExcludedUrlIsAccessibleWithoutCredentials() throws Exception { testResourceAccessWithoutCredentials(EXCLUDED_PROTECTED_RESOURCE_URL, 200, unprotectedResourceContentValidator()); } @Test public void testExcludedUrlIsAccessibleWithInvalidCredentials() throws Exception { testResourceAccess(EXCLUDED_PROTECTED_RESOURCE_URL, Optional.of(TEST_FAILING_BASIC_AUTH_HEADER), 200, unprotectedResourceContentValidator()); } private void validateProtectedResourceContent(JsonObject jsonObject) { assertThat(jsonObject .getJsonObject(BASIC_AUTH_CLIENT) .getString(USERNAME_FIELD), is(TEST_USER_NAME)); } private Consumer<Buffer> unprotectedResourceContentValidator() { return b -> assertThat(b.toString(), is(UNPROTECTED_RESOURCE_BODY)); } private void testResourceAccessWithoutCredentials(final String url, final int expectedHttpStatus, final Consumer<Buffer> bodyValidator) throws Exception { testResourceAccess(url, Optional.empty(), expectedHttpStatus, bodyValidator); } private Consumer<Buffer> unauthorizedContentValidator() { return body -> assertEquals(UNAUTHORIZED_BODY, body.toString()); } @Override protected void startWebServer() throws Exception { final Router router = Router.router(vertx); // Configure a pac4j stateless handler configured for basic http auth final Pac4jAuthProvider authProvider = new Pac4jAuthProvider(); SecurityHandlerOptions options = new SecurityHandlerOptions() .setAuthorizers(REQUIRE_ALL_AUTHORIZER) .setClients(BASIC_AUTH_CLIENT) .setMatchers(EXCLUDED_PATH_MATCHER_NAME); final SecurityHandler handler = new SecurityHandler(vertx, sessionStore, config(), authProvider, options); startWebServer(router, handler); } private Config config() { final Clients clients = new Clients(client()); final Config config = new Config(clients, authorizers(new ArrayList<>())); config.setMatcher(new ExcludedPathMatcher("^/private/public/.*$")); return config; } private Client client() { DirectBasicAuthClient client = new DirectBasicAuthClient(); client.setName("BasicAuthClient"); client.setAuthenticator(new SimpleTestUsernamePasswordAuthenticator()); return client; } }