blob: 11841141e5f11221097b7de7f25308d07fe05cb2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.sra;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import com.github.tomakehurst.wiremock.matching.AnythingPattern;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import java.io.IOException;
import java.net.URI;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLException;
import org.apache.syncope.common.lib.to.SRARouteTO;
import org.apache.syncope.common.lib.types.SRARouteFilter;
import org.apache.syncope.common.lib.types.SRARouteFilterFactory;
import org.apache.syncope.common.lib.types.SRARoutePredicate;
import org.apache.syncope.common.lib.types.SRARoutePredicateCond;
import org.apache.syncope.common.lib.types.SRARoutePredicateFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.netty.http.client.HttpClient;
@ActiveProfiles({ "tls" })
@TestPropertySource("classpath:sra-tls.properties")
public class TLSRouteProviderTest extends AbstractTest {
private WebTestClient webClient() throws SSLException {
SslContext sslContext = SslContextBuilder.forClient().
trustManager(InsecureTrustManagerFactory.INSTANCE).
build();
return webClient(sslContext);
}
private WebTestClient webClient(final SslContext sslContext) throws SSLException {
HttpClient httpClient = HttpClient.create().
secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
return WebTestClient.bindToServer(connector).baseUrl("https://localhost:" + sraPort).build();
}
@BeforeEach
public void clearRoutes() {
SyncopeCoreTestingServer.ROUTES.clear();
}
@Test
public void root() throws SSLException {
webClient().get().exchange().expectStatus().isNotFound();
}
@Test
public void clientAuth() throws SSLException, KeyStoreException, IOException, NoSuchAlgorithmException,
CertificateException, UnrecoverableKeyException, KeyManagementException {
KeyStore store = KeyStore.getInstance("PKCS12");
store.load(getClass().getResourceAsStream("/user.p12"), "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(store, "password".toCharArray());
SslContext sslContext = SslContextBuilder.forClient().
trustManager(InsecureTrustManagerFactory.INSTANCE).
keyManager(kmf).
build();
WebTestClient webClient = webClient(sslContext);
stubFor(get(urlEqualTo("/getWithClientAuth")).willReturn(aResponse()));
SRARouteTO route = new SRARouteTO();
route.setKey("getWithClientAuth");
route.setTarget(URI.create("http://localhost:" + wiremockPort));
route.getPredicates().add(new SRARoutePredicate.Builder().
factory(SRARoutePredicateFactory.METHOD).args("GET").build());
route.getPredicates().add(new SRARoutePredicate.Builder().
factory(SRARoutePredicateFactory.PATH).args("/getWithClientAuth").
cond(SRARoutePredicateCond.AND).build());
route.getFilters().add(new SRARouteFilter.Builder().
factory(SRARouteFilterFactory.CLIENT_CERTS_TO_REQUEST_HEADER).build());
SyncopeCoreTestingServer.ROUTES.put(route.getKey(), route);
routeRefresher.refresh();
webClient.get().uri("/getWithClientAuth").exchange().expectStatus().isOk();
verify(getRequestedFor(urlEqualTo("/getWithClientAuth")).
withHeader("X-Client-Certificate", new AnythingPattern()));
}
@Test
public void withoutClientCert() throws SSLException, KeyStoreException, IOException, NoSuchAlgorithmException,
CertificateException, UnrecoverableKeyException, KeyManagementException {
SslContext sslContext = SslContextBuilder.forClient().
trustManager(InsecureTrustManagerFactory.INSTANCE).
build();
WebTestClient webClient = webClient(sslContext);
stubFor(get(urlEqualTo("/withoutClientCert")).willReturn(aResponse()));
SRARouteTO route = new SRARouteTO();
route.setKey("withoutClientCert");
route.setTarget(URI.create("http://localhost:" + wiremockPort));
route.getPredicates().add(new SRARoutePredicate.Builder().
factory(SRARoutePredicateFactory.METHOD).args("GET").build());
route.getPredicates().add(new SRARoutePredicate.Builder().
factory(SRARoutePredicateFactory.PATH).args("/withoutClientCert").cond(SRARoutePredicateCond.AND).
build());
route.getFilters().add(new SRARouteFilter.Builder().
factory(SRARouteFilterFactory.CLIENT_CERTS_TO_REQUEST_HEADER).build());
SyncopeCoreTestingServer.ROUTES.put(route.getKey(), route);
routeRefresher.refresh();
webClient.get().uri("/withoutClientCert").exchange().
expectStatus().isOk().
expectHeader().doesNotExist("X-Client-Certificate");
}
}