Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/**
* 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.cxf.systest.jaxrs.security.oidc;

import java.net.URL;

import javax.ws.rs.core.Response;

import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys;
import org.apache.cxf.rs.security.jose.jwk.KeyType;
import org.apache.cxf.systest.jaxrs.security.SecurityTestUtil;
import org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuth2TestUtils;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;

import org.junit.AfterClass;
import org.junit.BeforeClass;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

/**
* Some tests for the OIDC Keys Service
*/
public class OIDCKeysServiceTest extends AbstractBusClientServerTestBase {

private static final SpringBusTestServer JCACHE_SERVER = new SpringBusTestServer("oidc-keys-jcache");


@BeforeClass
public static void startServers() throws Exception {
assertTrue("Server failed to launch", launchServer(JCACHE_SERVER));
}

@AfterClass
public static void cleanup() throws Exception {
SecurityTestUtil.cleanup();
}

@org.junit.Test
public void testGetRSAPublicKey() throws Exception {
URL busFile = OIDCFlowTest.class.getResource("client.xml");

String address = "https://localhost:" + JCACHE_SERVER.getPort() + "/services/";
WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
"alice", "security", busFile.toString());
client.accept("application/json");

client.path("keys/");
Response response = client.get();
JsonWebKeys jsonWebKeys = response.readEntity(JsonWebKeys.class);

assertEquals(1, jsonWebKeys.getKeys().size());

JsonWebKey jsonWebKey = jsonWebKeys.getKeys().get(0);
assertEquals(KeyType.RSA, jsonWebKey.getKeyType());
assertEquals("alice", jsonWebKey.getKeyId());
assertNotNull(jsonWebKey.getProperty("n"));
assertNotNull(jsonWebKey.getProperty("e"));
// Check we don't send the private key back
checkPrivateKeyParametersNotPresent(jsonWebKeys);
}

@org.junit.Test
public void testGetJWKRSAPublicKey() throws Exception {
URL busFile = OIDCFlowTest.class.getResource("client.xml");

String address = "https://localhost:" + JCACHE_SERVER.getPort() + "/services2/";
WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
"alice", "security", busFile.toString());
client.accept("application/json");

client.path("keys/");
Response response = client.get();
JsonWebKeys jsonWebKeys = response.readEntity(JsonWebKeys.class);

assertEquals(1, jsonWebKeys.getKeys().size());

JsonWebKey jsonWebKey = jsonWebKeys.getKeys().get(0);
assertEquals(KeyType.RSA, jsonWebKey.getKeyType());
assertEquals("2011-04-29", jsonWebKey.getKeyId());
assertNotNull(jsonWebKey.getProperty("n"));
assertNotNull(jsonWebKey.getProperty("e"));
// Check we don't send the private key back
checkPrivateKeyParametersNotPresent(jsonWebKeys);
}

@org.junit.Test
public void testGetJWKECPublicKey() throws Exception {
URL busFile = OIDCFlowTest.class.getResource("client.xml");

String address = "https://localhost:" + JCACHE_SERVER.getPort() + "/services3/";
WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
"alice", "security", busFile.toString());
client.accept("application/json");

client.path("keys/");
Response response = client.get();
JsonWebKeys jsonWebKeys = response.readEntity(JsonWebKeys.class);

assertEquals(1, jsonWebKeys.getKeys().size());

JsonWebKey jsonWebKey = jsonWebKeys.getKeys().get(0);
assertEquals(KeyType.EC, jsonWebKey.getKeyType());
assertEquals("ECKey", jsonWebKey.getKeyId());
assertNotNull(jsonWebKey.getProperty("x"));
assertNotNull(jsonWebKey.getProperty("y"));
// Check we don't send the private key back
checkPrivateKeyParametersNotPresent(jsonWebKeys);
}

@org.junit.Test
public void testGetJWKHMAC() throws Exception {
URL busFile = OIDCFlowTest.class.getResource("client.xml");

String address = "https://localhost:" + JCACHE_SERVER.getPort() + "/services4/";
WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
"alice", "security", busFile.toString());
client.accept("application/json");

client.path("keys/");
Response response = client.get();
JsonWebKeys jsonWebKeys = response.readEntity(JsonWebKeys.class);

// We don't allow sending secret keys back from the key service by default
assertNull(jsonWebKeys.getKeys());
}

@org.junit.Test
public void testGetJWKHMACExplicitlyAllowed() throws Exception {
URL busFile = OIDCFlowTest.class.getResource("client.xml");

String address = "https://localhost:" + JCACHE_SERVER.getPort() + "/services5/";
WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
"alice", "security", busFile.toString());
client.accept("application/json");

client.path("keys/");
Response response = client.get();
JsonWebKeys jsonWebKeys = response.readEntity(JsonWebKeys.class);

// Here we explicitly allow sending back secret keys
assertEquals(1, jsonWebKeys.getKeys().size());
}

@org.junit.Test
public void testGetJWKMultipleKeys() throws Exception {
URL busFile = OIDCFlowTest.class.getResource("client.xml");

String address = "https://localhost:" + JCACHE_SERVER.getPort() + "/services6/";
WebClient client = WebClient.create(address, OAuth2TestUtils.setupProviders(),
"alice", "security", busFile.toString());
client.accept("application/json");

client.path("keys/");
Response response = client.get();
JsonWebKeys jsonWebKeys = response.readEntity(JsonWebKeys.class);

assertEquals(2, jsonWebKeys.getKeys().size());

// Check we don't send the private key back
checkPrivateKeyParametersNotPresent(jsonWebKeys);
}

private void checkPrivateKeyParametersNotPresent(JsonWebKeys jsonWebKeys) {
for (JsonWebKey jsonWebKey : jsonWebKeys.getKeys()) {
assertNull(jsonWebKey.getProperty("d"));
assertNull(jsonWebKey.getProperty("p"));
assertNull(jsonWebKey.getProperty("q"));
assertNull(jsonWebKey.getProperty("dp"));
assertNull(jsonWebKey.getProperty("dq"));
assertNull(jsonWebKey.getProperty("qi"));
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
<cxf:properties>
<entry key="org.apache.cxf.jaxrs.bus.providers" value-ref="busProviders"/>
</cxf:properties>
</cxf:bus>
<!-- providers -->
<util:list id="busProviders">
<ref bean="oauthJson"/>
</util:list>
<bean id="oauthJson" class="org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider"/>

<httpj:engine-factory id="tls-config">
<httpj:engine port="${testutil.ports.oidc-keys-jcache}">
<httpj:tlsServerParameters>
<sec:keyManagers keyPassword="password">
<sec:keyStore type="JKS" password="password" resource="keys/Bethal.jks"/>
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore type="JKS" password="password" resource="keys/Truststore.jks"/>
</sec:trustManagers>
<sec:clientAuthentication want="false" required="false"/>
</httpj:tlsServerParameters>
<httpj:sessionSupport>true</httpj:sessionSupport>
</httpj:engine>
</httpj:engine-factory>

<bean id="oidcKeysService" class="org.apache.cxf.rs.security.oidc.idp.OidcKeysService"/>

<jaxrs:server
depends-on="tls-config"
address="https://localhost:${testutil.ports.oidc-keys-jcache}/services">
<jaxrs:serviceBeans>
<ref bean="oidcKeysService"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.apache.cxf.rs.security.jose.jaxrs.JsonWebKeysProvider"/>
</jaxrs:providers>
<jaxrs:properties>
<entry key="rs.security.keystore.type" value="jks" />
<entry key="rs.security.keystore.alias" value="alice"/>
<entry key="rs.security.keystore.password" value="password"/>
<entry key="rs.security.key.password" value="password"/>
<entry key="rs.security.keystore.file" value="keys/alice.jks" />
</jaxrs:properties>
</jaxrs:server>

<bean id="oidcKeysService2" class="org.apache.cxf.rs.security.oidc.idp.OidcKeysService"/>

<jaxrs:server
depends-on="tls-config"
address="https://localhost:${testutil.ports.oidc-keys-jcache}/services2">
<jaxrs:serviceBeans>
<ref bean="oidcKeysService2"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.apache.cxf.rs.security.jose.jaxrs.JsonWebKeysProvider"/>
</jaxrs:providers>
<jaxrs:properties>
<entry key="rs.security.keystore.type" value="jwk" />
<entry key="rs.security.keystore.alias" value="2011-04-29"/>
<entry key="rs.security.keystore.file" value="org/apache/cxf/systest/jaxrs/security/certs/jwkPrivateSet.txt" />
</jaxrs:properties>
</jaxrs:server>

<bean id="oidcKeysService3" class="org.apache.cxf.rs.security.oidc.idp.OidcKeysService"/>

<jaxrs:server
depends-on="tls-config"
address="https://localhost:${testutil.ports.oidc-keys-jcache}/services3">
<jaxrs:serviceBeans>
<ref bean="oidcKeysService3"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.apache.cxf.rs.security.jose.jaxrs.JsonWebKeysProvider"/>
</jaxrs:providers>
<jaxrs:properties>
<entry key="rs.security.keystore.type" value="jwk" />
<entry key="rs.security.keystore.alias" value="ECKey"/>
<entry key="rs.security.keystore.file" value="org/apache/cxf/systest/jaxrs/security/certs/jwkPrivateSet.txt" />
</jaxrs:properties>
</jaxrs:server>

<bean id="oidcKeysService4" class="org.apache.cxf.rs.security.oidc.idp.OidcKeysService"/>

<jaxrs:server
depends-on="tls-config"
address="https://localhost:${testutil.ports.oidc-keys-jcache}/services4">
<jaxrs:serviceBeans>
<ref bean="oidcKeysService4"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.apache.cxf.rs.security.jose.jaxrs.JsonWebKeysProvider"/>
</jaxrs:providers>
<jaxrs:properties>
<entry key="rs.security.keystore.type" value="jwk" />
<entry key="rs.security.keystore.alias" value="HMAC512Key"/>
<entry key="rs.security.keystore.file" value="org/apache/cxf/systest/jaxrs/security/certs/jwkPrivateSet.txt" />
</jaxrs:properties>
</jaxrs:server>

<bean id="oidcKeysService5" class="org.apache.cxf.rs.security.oidc.idp.OidcKeysService">
<property name="stripPrivateParameters" value="false"/>
</bean>

<jaxrs:server
depends-on="tls-config"
address="https://localhost:${testutil.ports.oidc-keys-jcache}/services5">
<jaxrs:serviceBeans>
<ref bean="oidcKeysService5"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.apache.cxf.rs.security.jose.jaxrs.JsonWebKeysProvider"/>
</jaxrs:providers>
<jaxrs:properties>
<entry key="rs.security.keystore.type" value="jwk" />
<entry key="rs.security.keystore.alias" value="HMAC512Key"/>
<entry key="rs.security.keystore.file" value="org/apache/cxf/systest/jaxrs/security/certs/jwkPrivateSet.txt" />
</jaxrs:properties>
</jaxrs:server>


<bean id="oidcKeysService6" class="org.apache.cxf.rs.security.oidc.idp.OidcKeysService"/>

<jaxrs:server
depends-on="tls-config"
address="https://localhost:${testutil.ports.oidc-keys-jcache}/services6">
<jaxrs:serviceBeans>
<ref bean="oidcKeysService6"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.apache.cxf.rs.security.jose.jaxrs.JsonWebKeysProvider"/>
</jaxrs:providers>
<jaxrs:properties>
<entry key="rs.security.keystore.type" value="jwk" />
<entry key="rs.security.keystore.aliases" value="2011-04-29,ECKey"/>
<entry key="rs.security.keystore.file" value="org/apache/cxf/systest/jaxrs/security/certs/jwkPrivateSet.txt" />
</jaxrs:properties>
</jaxrs:server>

</beans>