fediz-oidc: sync resources with systests; register redirect servlets
diff --git a/services/idp/src/main/webapp/WEB-INF/config/idp-core-servlet.xml b/services/idp/src/main/webapp/WEB-INF/config/idp-core-servlet.xml
index 3d62ad9..cbf2450 100644
--- a/services/idp/src/main/webapp/WEB-INF/config/idp-core-servlet.xml
+++ b/services/idp/src/main/webapp/WEB-INF/config/idp-core-servlet.xml
@@ -35,9 +35,9 @@
<context:component-scan base-package="org.apache.cxf.fediz.service.idp.beans" />
<mvc:resources mapping="/images/**" location="/resources/images/" />
-
+
<mvc:resources mapping="/swagger/**" location="/resources/swagger/" />
-
+
<mvc:view-controller path="/" view-name="index" />
<mvc:view-controller path="/federation/up/login" view-name="signinform" />
diff --git a/services/oidc/src/main/webapp/WEB-INF/data-manager.xml b/services/oidc/src/main/webapp/WEB-INF/data-manager.xml
index 57feaf0..7fd7d49 100644
--- a/services/oidc/src/main/webapp/WEB-INF/data-manager.xml
+++ b/services/oidc/src/main/webapp/WEB-INF/data-manager.xml
@@ -43,8 +43,8 @@
-->
<util:map id="supportedClaims">
<entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role" value="roles" />
- </util:map>
-
+ </util:map>
+
<!--
List of required scopes that must be available in request URIs when
client redirects users to OIDC
@@ -60,17 +60,16 @@
<util:list id="invisibleToClientScopes">
<value>refreshToken</value>
</util:list>
-
+
<!--
To support the alternative data persistence strategies: either register a custom
AbstractCodeDataProvider extension or implement AuthorizationCodeDataProvider directly
- -->
+ -->
<bean id="oauthProvider"
class="org.apache.cxf.fediz.service.oidc.OAuthDataProviderImpl"
init-method="init" destroy-method="close">
<!-- List of accepted scopes -->
<property name="supportedScopes" ref="supportedScopes"/>
-
<!--
List of scopes that the consent/authorization form should make
selected by default. For example, asking a user to do an extra click
@@ -86,15 +85,14 @@
<!--
<property name="supportPreauthorizedTokens" value="true"/>
-->
-
</bean>
- <!-- Custom SubjectCreator where IdToken is created -->
+ <!-- Custom SubjectCreator where IdToken is created -->
<bean id="subjectCreator" class="org.apache.cxf.fediz.service.oidc.FedizSubjectCreator">
<property name="idTokenIssuer" value="accounts.fediz.com"/>
- <!-- List of additional claims which can be optionally added to IdToken -->
+ <!-- List of additional claims which can be optionally added to IdToken -->
<property name="supportedClaims" ref="supportedClaims"/>
</bean>
-
+
</beans>
diff --git a/systests/oidc/pom.xml b/systests/oidc/pom.xml
index 63f1fc6..cbb6566 100644
--- a/systests/oidc/pom.xml
+++ b/systests/oidc/pom.xml
@@ -34,6 +34,7 @@
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>${htmlunit.version}</version>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
@@ -83,6 +84,7 @@
<version>${cxf.version}</version>
<scope>test</scope>
</dependency>
+ <!-- org.apache.cxf.ws.security.trust.STSLoginModule -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
@@ -150,6 +152,7 @@
<type>war</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/tomcat/rp/webapps/fediz-oidc-tomcat</outputDirectory>
+ <excludes>META-INF/context.xml</excludes>
</artifactItem>
<artifactItem>
<groupId>org.apache.cxf.fediz</groupId>
@@ -158,6 +161,7 @@
<type>war</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/tomcat/rp/webapps/fediz-oidc-spring</outputDirectory>
+ <excludes>META-INF/context.xml</excludes>
</artifactItem>
<artifactItem>
<groupId>org.apache.cxf.fediz.systests</groupId>
@@ -212,7 +216,7 @@
</goals>
<configuration>
<outputDirectory>${project.build.directory}/tomcat/idp/webapps/fediz-idp/WEB-INF/classes</outputDirectory>
- <resources>
+ <resources>
<resource>
<directory>${basedir}/src/test/resources/realma</directory>
<includes>
@@ -231,7 +235,7 @@
</goals>
<configuration>
<outputDirectory>${project.build.directory}/tomcat/rp/webapps/fediz-oidc-tomcat/WEB-INF</outputDirectory>
- <resources>
+ <resources>
<resource>
<directory>${basedir}/src/test/resources/oidc</directory>
<includes>
@@ -273,27 +277,6 @@
</executions>
</plugin>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-antrun-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <phase>pre-integration-test</phase>
- <goals>
- <goal>run</goal>
- </goals>
- <configuration>
- <tasks>
- <delete>
- <fileset dir="${project.build.directory}/tomcat/rp/webapps/fediz-oidc-tomcat/META-INF" includes="context.xml" />
- <fileset dir="${project.build.directory}/tomcat/rp/webapps/fediz-oidc-spring/META-INF" includes="context.xml" />
- </delete>
- </tasks>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<inherited>true</inherited>
<executions>
diff --git a/systests/oidc/src/test/java/org/apache/cxf/fediz/systests/oidc/AbstractOIDCTest.java b/systests/oidc/src/test/java/org/apache/cxf/fediz/systests/oidc/AbstractOIDCTest.java
index f1eedf1..9857421 100644
--- a/systests/oidc/src/test/java/org/apache/cxf/fediz/systests/oidc/AbstractOIDCTest.java
+++ b/systests/oidc/src/test/java/org/apache/cxf/fediz/systests/oidc/AbstractOIDCTest.java
@@ -22,7 +22,6 @@
import java.io.IOException;
import java.io.InputStream;
-import java.net.ConnectException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -35,21 +34,25 @@
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
+import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.ws.rs.core.Response.Status;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.HttpMethod;
+import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.UnexpectedPage;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequest;
-import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlButton;
@@ -60,7 +63,6 @@
import com.gargoylesoftware.htmlunit.html.HtmlTable;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
-import com.gargoylesoftware.htmlunit.util.WebConnectionWrapper;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
@@ -74,12 +76,12 @@
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.conn.HttpHostConnectException;
import org.apache.wss4j.common.util.Loader;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -88,9 +90,14 @@
*/
abstract class AbstractOIDCTest {
- private static final String IDP_HTTPS_PORT = System.getProperty("idp.https.port");
+ private static final Integer IDP_HTTPS_PORT = Integer.getInteger("idp.https.port");
private static final String RP_HTTPS_PORT = System.getProperty("rp.https.port");
+ private static final String CALLBACK_CONTEXT_1 = "/callback1";
+ private static final String REDIRECT_URL_1 = "https://127.0.0.1:" + RP_HTTPS_PORT + CALLBACK_CONTEXT_1;
+ private static final String CALLBACK_CONTEXT_2 = "/callback2";
+ private static final String REDIRECT_URL_2 = "https://127.0.0.1:" + RP_HTTPS_PORT + CALLBACK_CONTEXT_2;
+
private static Tomcat idpServer;
private static Tomcat rpServer;
@@ -103,12 +110,12 @@
assertNotNull("Property 'rp.https.port' null", RP_HTTPS_PORT);
idpServer = startServer(IDP_HTTPS_PORT, null, null);
- rpServer = startServer(RP_HTTPS_PORT, servletContextName, fedizConfigPath);
+ rpServer = startServer(Integer.parseInt(RP_HTTPS_PORT), servletContextName, fedizConfigPath);
- loginToClientsPage(RP_HTTPS_PORT, IDP_HTTPS_PORT, servletContextName);
+ loginToClientsPage(RP_HTTPS_PORT, servletContextName);
}
- private static Tomcat startServer(String port, String servletContextName, String fedizConfigPath)
+ private static Tomcat startServer(int port, String servletContextName, String fedizConfigPath)
throws ServletException, LifecycleException, IOException {
Tomcat server = new Tomcat();
server.setPort(0);
@@ -119,7 +126,7 @@
server.getHost().setDeployOnStartup(true);
Connector httpsConnector = new Connector();
- httpsConnector.setPort(Integer.parseInt(port));
+ httpsConnector.setPort(port);
httpsConnector.setSecure(true);
httpsConnector.setScheme("https");
httpsConnector.setAttribute("sslProtocol", "TLS");
@@ -145,7 +152,7 @@
httpsConnector.setAttribute("clientAuth", "false");
Path rpWebapp = targetDir.resolve(server.getHost().getAppBase()).resolve(servletContextName);
- Context cxt = server.addWebapp(servletContextName, rpWebapp.toString());
+ Context ctx = server.addWebapp(servletContextName, rpWebapp.toString());
// Substitute the IDP port. Necessary if running the test in eclipse where port filtering doesn't seem
// to work
@@ -153,14 +160,22 @@
try (InputStream is = AbstractOIDCTest.class.getResourceAsStream('/' + fedizConfigPath)) {
byte[] content = new byte[is.available()];
is.read(content);
- Files.write(fedizConfig, new String(content).replace("${idp.https.port}", IDP_HTTPS_PORT).getBytes());
+ Files.write(fedizConfig,
+ new String(content).replace("${idp.https.port}", Integer.toString(IDP_HTTPS_PORT)).getBytes());
}
if (!fedizConfigPath.contains("spring")) {
FederationAuthenticator fa = new FederationAuthenticator();
fa.setConfigFile(fedizConfig.toString());
- cxt.getPipeline().addValve(fa);
+ ctx.getPipeline().addValve(fa);
}
+
+ // callback
+ ctx = server.addContext("", null);
+ final String servletName = "callback";
+ Tomcat.addServlet(ctx, servletName, new CallbackServlet());
+ ctx.addServletMappingDecoded(CALLBACK_CONTEXT_1, servletName);
+ ctx.addServletMappingDecoded(CALLBACK_CONTEXT_2, servletName);
}
server.getService().addConnector(httpsConnector);
@@ -172,7 +187,7 @@
protected static void shutdownServer(String servletContextName) throws Exception {
try {
- loginToClientsPageAndDeleteClient(RP_HTTPS_PORT, IDP_HTTPS_PORT, servletContextName);
+ loginToClientsPageAndDeleteClient(RP_HTTPS_PORT, servletContextName);
} finally {
shutdownServer(idpServer);
shutdownServer(rpServer);
@@ -189,10 +204,6 @@
}
}
- private String getIdpHttpsPort() {
- return IDP_HTTPS_PORT;
- }
-
private String getRpHttpsPort() {
return RP_HTTPS_PORT;
}
@@ -200,25 +211,25 @@
protected abstract String getServletContextName();
// Runs as BeforeClass: Login to the OIDC Clients page + create two new clients
- private static void loginToClientsPage(String rpPort, String idpPort, String servletContext) throws Exception {
+ private static void loginToClientsPage(String rpPort, String servletContext) throws Exception {
String url = "https://localhost:" + rpPort + "/" + servletContext + "/console/clients";
String user = "alice";
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, idpPort);
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
// Now try to register a new client
HtmlPage registeredClientPage =
- registerNewClient(webClient, url, "new-client", "https://127.0.0.1",
+ registerNewClient(webClient, url, "new-client", REDIRECT_URL_1,
"https://cxf.apache.org", "https://localhost:12345");
String registeredClientPageBody = registeredClientPage.getBody().getTextContent();
assertTrue(registeredClientPageBody.contains("Registered Clients"));
assertTrue(registeredClientPageBody.contains("new-client"));
- assertTrue(registeredClientPageBody.contains("https://127.0.0.1"));
+ assertTrue(registeredClientPageBody.contains(REDIRECT_URL_1));
HtmlTable table = registeredClientPage.getHtmlElementById("registered_clients");
storedClientId = table.getCellAt(1, 1).asText().trim();
@@ -231,14 +242,14 @@
// Try to register another new client
registeredClientPage =
- registerNewClient(webClient, url, "new-client2", "https://127.0.1.1",
- "https://ws.apache.org", "https://localhost:12345");
+ registerNewClient(webClient, url, "new-client2", REDIRECT_URL_2,
+ "https://ws.apache.org", "https://localhost:12346");
registeredClientPageBody = registeredClientPage.getBody().getTextContent();
assertTrue(registeredClientPageBody.contains("Registered Clients"));
assertTrue(registeredClientPageBody.contains("new-client"));
- assertTrue(registeredClientPageBody.contains("https://127.0.0.1"));
+ assertTrue(registeredClientPageBody.contains(REDIRECT_URL_1));
assertTrue(registeredClientPageBody.contains("new-client2"));
- assertTrue(registeredClientPageBody.contains("https://127.0.1.1"));
+ assertTrue(registeredClientPageBody.contains(REDIRECT_URL_2));
table = registeredClientPage.getHtmlElementById("registered_clients");
storedClient2Id = table.getCellAt(2, 1).asText().trim();
@@ -275,14 +286,14 @@
}
// Runs as AfterClass: Login to the OIDC Clients page + delete the created clients!
- private static void loginToClientsPageAndDeleteClient(String rpPort, String idpPort, String servletContext)
+ private static void loginToClientsPageAndDeleteClient(String rpPort, String servletContext)
throws Exception {
String url = "https://localhost:" + rpPort + "/" + servletContext + "/console/clients";
String user = "alice";
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, idpPort);
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -330,7 +341,7 @@
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -353,8 +364,8 @@
// Check the redirect URI
String redirectURI = table.getCellAt(1, 3).asText().trim();
- assertTrue("https://127.0.0.1".equals(redirectURI)
- || "https://127.0.1.1".equals(redirectURI));
+ assertTrue(REDIRECT_URL_1.equals(redirectURI)
+ || REDIRECT_URL_2.equals(redirectURI));
// Now check the specific client page
HtmlPage clientPage = webClient.getPage(url + "/" + clientId);
@@ -372,7 +383,7 @@
String password = "bob";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -389,15 +400,15 @@
@org.junit.Test
public void testOIDCLoginForClient1() throws Exception {
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?";
- url += "client_id=" + storedClientId;
- url += "&response_type=code";
- url += "&scope=openid";
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id=" + storedClientId
+ + "&response_type=code"
+ + "&scope=openid";
String user = "alice";
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
assertNotNull(authorizationCode);
@@ -406,10 +417,10 @@
url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/oauth2/token";
WebRequest request = new WebRequest(new URL(url), HttpMethod.POST);
- request.setRequestParameters(new ArrayList<NameValuePair>());
- request.getRequestParameters().add(new NameValuePair("client_id", storedClientId));
- request.getRequestParameters().add(new NameValuePair("grant_type", "authorization_code"));
- request.getRequestParameters().add(new NameValuePair("code", authorizationCode));
+ request.setRequestParameters(Arrays.asList(
+ new NameValuePair("client_id", storedClientId),
+ new NameValuePair("grant_type", "authorization_code"),
+ new NameValuePair("code", authorizationCode)));
webClient.getOptions().setJavaScriptEnabled(false);
final UnexpectedPage responsePage = webClient.getPage(request);
@@ -426,15 +437,15 @@
@org.junit.Test
public void testOIDCLoginForClient2() throws Exception {
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?";
- url += "client_id=" + storedClient2Id;
- url += "&response_type=code";
- url += "&scope=openid";
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id=" + storedClient2Id
+ + "&response_type=code"
+ + "&scope=openid";
String user = "alice";
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
assertNotNull(authorizationCode);
@@ -443,10 +454,10 @@
url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/oauth2/token";
WebRequest request = new WebRequest(new URL(url), HttpMethod.POST);
- request.setRequestParameters(new ArrayList<NameValuePair>());
- request.getRequestParameters().add(new NameValuePair("client_id", storedClient2Id));
- request.getRequestParameters().add(new NameValuePair("grant_type", "authorization_code"));
- request.getRequestParameters().add(new NameValuePair("code", authorizationCode));
+ request.setRequestParameters(Arrays.asList(
+ new NameValuePair("client_id", storedClient2Id),
+ new NameValuePair("grant_type", "authorization_code"),
+ new NameValuePair("code", authorizationCode)));
webClient.getOptions().setJavaScriptEnabled(false);
final UnexpectedPage responsePage = webClient.getPage(request);
@@ -463,15 +474,15 @@
@org.junit.Test
public void testUsingCodeForOtherClient() throws Exception {
// Get the code for the first client
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?";
- url += "client_id=" + storedClientId;
- url += "&response_type=code";
- url += "&scope=openid";
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id=" + storedClientId
+ + "&response_type=code"
+ + "&scope=openid";
String user = "alice";
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
assertNotNull(authorizationCode);
@@ -479,76 +490,73 @@
url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/oauth2/token";
WebRequest request = new WebRequest(new URL(url), HttpMethod.POST);
- request.setRequestParameters(new ArrayList<NameValuePair>());
- request.getRequestParameters().add(new NameValuePair("client_id", storedClient2Id));
- request.getRequestParameters().add(new NameValuePair("grant_type", "authorization_code"));
- request.getRequestParameters().add(new NameValuePair("code", authorizationCode));
+ request.setRequestParameters(Arrays.asList(
+ new NameValuePair("client_id", storedClient2Id),
+ new NameValuePair("grant_type", "authorization_code"),
+ new NameValuePair("code", authorizationCode)));
webClient.getOptions().setJavaScriptEnabled(false);
try {
webClient.getPage(request);
fail();
} catch (FailingHttpStatusCodeException ex) {
- // expected
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), ex.getStatusCode());
}
+
+ webClient.close();
}
@org.junit.Test
public void testBadClientId() throws Exception {
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?";
- url += "client_id=" + storedClientId + 2;
- url += "&response_type=code";
- url += "&scope=openid";
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id=" + storedClientId.substring(1)
+ + "&response_type=code"
+ + "&scope=openid";
String user = "alice";
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
-
- String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
- assertNull(authorizationCode);
-
- webClient.close();
+ try (WebClient webClient = setupWebClient(user, password)) {
+ final String response = loginAndGetAuthorizationCode(url, webClient);
+ assertTrue(response.contains("invalid_request"));
+ }
}
@org.junit.Test
public void testEmptyClientId() throws Exception {
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?";
- url += "client_id=";
- url += "&response_type=code";
- url += "&scope=openid";
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id="
+ + "&response_type=code"
+ + "&scope=openid";
String user = "alice";
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
-
- String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
- assertNull(authorizationCode);
-
- webClient.close();
+ try (WebClient webClient = setupWebClient(user, password)) {
+ final String response = loginAndGetAuthorizationCode(url, webClient);
+ assertTrue(response.contains("invalid_request"));
+ }
}
@org.junit.Test
public void testIncorrectRedirectURI() throws Exception {
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?";
- url += "client_id=" + storedClientId;
- url += "&response_type=code";
- url += "&scope=openid";
- url += "&redirect_uri=https://127.0.0.5";
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id=" + storedClientId
+ + "&response_type=code"
+ + "&scope=openid"
+ + "&redirect_uri=https://127.0.0.5";
String user = "alice";
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
-
- String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
- assertNull(authorizationCode);
-
- webClient.close();
+ try (WebClient webClient = setupWebClient(user, password);) {
+ loginAndGetAuthorizationCode(url, webClient);
+ } catch (FailingHttpStatusCodeException e) {
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), e.getStatusCode());
+ }
}
@org.junit.Test
@@ -558,7 +566,7 @@
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -578,7 +586,7 @@
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -598,7 +606,7 @@
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -618,7 +626,7 @@
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -638,7 +646,7 @@
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -656,10 +664,10 @@
String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/oauth2/token";
WebRequest request = new WebRequest(new URL(url), HttpMethod.POST);
- request.setRequestParameters(new ArrayList<NameValuePair>());
- request.getRequestParameters().add(new NameValuePair("client_id", "alice"));
- request.getRequestParameters().add(new NameValuePair("client_secret", "ecila"));
- request.getRequestParameters().add(new NameValuePair("grant_type", "client_credentials"));
+ request.setRequestParameters(Arrays.asList(
+ new NameValuePair("client_id", "alice"),
+ new NameValuePair("client_secret", "ecila"),
+ new NameValuePair("grant_type", "client_credentials")));
final WebClient webClient = new WebClient();
webClient.getOptions().setUseInsecureSSL(true);
@@ -679,7 +687,7 @@
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -709,43 +717,34 @@
@org.junit.Test
public void testLogout() throws Exception {
// 1. Log in
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?";
- url += "client_id=" + storedClientId;
- url += "&response_type=code";
- url += "&scope=openid";
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id=" + storedClientId
+ + "&response_type=code"
+ + "&scope=openid";
String user = "alice";
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
assertNotNull(authorizationCode);
// 2. Get another authorization code without username/password. This should work as we are
// logged on
webClient.getCredentialsProvider().clear();
- CodeWebConnectionWrapper wrapper = new CodeWebConnectionWrapper(webClient);
- try {
- webClient.getPage(url);
- fail();
- } catch (ConnectException t) {
- // expected
- }
-
- wrapper.close();
- authorizationCode = wrapper.getCode();
+ authorizationCode = webClient.getPage(url).getWebResponse().getContentAsString();
assertNotNull(authorizationCode);
// 3. Log out
- String logoutUrl = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/logout?";
- logoutUrl += "client_id=" + storedClientId;
+ String logoutUrl = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/logout"
+ + "?client_id=" + storedClientId;
webClient.getOptions().setJavaScriptEnabled(false);
try {
webClient.getPage(logoutUrl);
fail();
- } catch (Exception ex) {
+ } catch (HttpHostConnectException ex) {
assertTrue(ex.getMessage().contains("Connect to localhost:12345"));
}
@@ -754,8 +753,8 @@
try {
loginAndGetAuthorizationCode(url, webClient);
fail("Failure expected after logout");
- } catch (Exception ex) {
- assertTrue(ex.getMessage().contains("401"));
+ } catch (FailingHttpStatusCodeException ex) {
+ assertEquals(Status.UNAUTHORIZED.getStatusCode(), ex.getStatusCode());
}
webClient.close();
@@ -764,21 +763,21 @@
@org.junit.Test
public void testLogoutViaTokenHint() throws Exception {
// 1. Log in
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?";
- url += "client_id=" + storedClientId;
- url += "&response_type=code";
- url += "&scope=openid";
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id=" + storedClientId
+ + "&response_type=code"
+ + "&scope=openid";
String user = "alice";
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
assertNotNull(authorizationCode);
webClient.getCredentialsProvider().clear();
// Now use the code to get an IdToken
- WebClient webClient2 = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient2 = setupWebClient("", "");
String data = storedClientId + ":" + storedClientPassword;
String authorizationHeader = "Basic "
+ Base64.getEncoder().encodeToString(data.getBytes(StandardCharsets.UTF_8));
@@ -786,12 +785,11 @@
String tokenUrl = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/oauth2/token";
WebRequest request = new WebRequest(new URL(tokenUrl), HttpMethod.POST);
- request.setRequestParameters(new ArrayList<NameValuePair>());
- request.getRequestParameters().add(new NameValuePair("client_id", storedClientId));
- request.getRequestParameters().add(new NameValuePair("grant_type", "authorization_code"));
- request.getRequestParameters().add(new NameValuePair("code", authorizationCode));
+ request.setRequestParameters(Arrays.asList(
+ new NameValuePair("client_id", storedClientId),
+ new NameValuePair("grant_type", "authorization_code"),
+ new NameValuePair("code", authorizationCode)));
- webClient2.getOptions().setJavaScriptEnabled(false);
final UnexpectedPage responsePage = webClient2.getPage(request);
String response = responsePage.getWebResponse().getContentAsString();
@@ -803,8 +801,8 @@
webClient2.close();
// 2. Log out using the token hint
- String logoutUrl = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/logout?";
- logoutUrl += "id_token_hint=" + idToken;
+ String logoutUrl = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/logout"
+ + "?id_token_hint=" + idToken;
webClient.getOptions().setJavaScriptEnabled(false);
try {
@@ -834,7 +832,7 @@
String password = "ecila";
// Login to the client page successfully
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
HtmlPage loginPage = login(url, webClient);
final String bodyTextContent = loginPage.getBody().getTextContent();
assertTrue(bodyTextContent.contains("Registered Clients"));
@@ -842,15 +840,14 @@
// Register a new client
WebRequest request = new WebRequest(new URL(url), HttpMethod.POST);
- request.setRequestParameters(new ArrayList<NameValuePair>());
-
- request.getRequestParameters().add(new NameValuePair("client_name", "bad_client"));
- request.getRequestParameters().add(new NameValuePair("client_type", "confidential"));
- request.getRequestParameters().add(new NameValuePair("client_redirectURI", "https://127.0.0.1"));
- request.getRequestParameters().add(new NameValuePair("client_audience", ""));
- request.getRequestParameters().add(new NameValuePair("client_logoutURI", ""));
- request.getRequestParameters().add(new NameValuePair("client_homeRealm", ""));
- request.getRequestParameters().add(new NameValuePair("client_csrfToken", "12345"));
+ request.setRequestParameters(Arrays.asList(
+ new NameValuePair("client_name", "bad_client"),
+ new NameValuePair("client_type", "confidential"),
+ new NameValuePair("client_redirectURI", "https://127.0.0.1"),
+ new NameValuePair("client_audience", ""),
+ new NameValuePair("client_logoutURI", ""),
+ new NameValuePair("client_homeRealm", ""),
+ new NameValuePair("client_csrfToken", "12345")));
HtmlPage registeredClientPage = webClient.getPage(request);
assertTrue(registeredClientPage.asXml().contains("Invalid CSRF Token"));
@@ -861,8 +858,8 @@
@org.junit.Test
public void testOIDCLoginForClient1WithRoles() throws Exception {
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?"
- + "client_id=" + storedClientId
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id=" + storedClientId
+ "&response_type=code"
+ "&scope=openid"
+ "&claims=roles";
@@ -870,7 +867,7 @@
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
assertNotNull(authorizationCode);
@@ -879,10 +876,10 @@
url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/oauth2/token";
WebRequest request = new WebRequest(new URL(url), HttpMethod.POST);
- request.setRequestParameters(new ArrayList<NameValuePair>());
- request.getRequestParameters().add(new NameValuePair("client_id", storedClientId));
- request.getRequestParameters().add(new NameValuePair("grant_type", "authorization_code"));
- request.getRequestParameters().add(new NameValuePair("code", authorizationCode));
+ request.setRequestParameters(Arrays.asList(
+ new NameValuePair("client_id", storedClientId),
+ new NameValuePair("grant_type", "authorization_code"),
+ new NameValuePair("code", authorizationCode)));
webClient.getOptions().setJavaScriptEnabled(false);
final UnexpectedPage responsePage = webClient.getPage(request);
@@ -899,15 +896,15 @@
@org.junit.Test
public void testOIDCLoginForClient1WithRolesScope() throws Exception {
- String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize?"
- + "client_id=" + storedClientId
+ String url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/idp/authorize"
+ + "?client_id=" + storedClientId
+ "&response_type=code"
+ "&scope=openid%20roles";
String user = "alice";
String password = "ecila";
// Login to the OIDC token endpoint + get the authorization code
- WebClient webClient = setupWebClient(user, password, getIdpHttpsPort());
+ WebClient webClient = setupWebClient(user, password);
String authorizationCode = loginAndGetAuthorizationCode(url, webClient);
assertNotNull(authorizationCode);
@@ -916,10 +913,10 @@
url = "https://localhost:" + getRpHttpsPort() + "/" + getServletContextName() + "/oauth2/token";
WebRequest request = new WebRequest(new URL(url), HttpMethod.POST);
- request.setRequestParameters(new ArrayList<NameValuePair>());
- request.getRequestParameters().add(new NameValuePair("client_id", storedClientId));
- request.getRequestParameters().add(new NameValuePair("grant_type", "authorization_code"));
- request.getRequestParameters().add(new NameValuePair("code", authorizationCode));
+ request.setRequestParameters(Arrays.asList(
+ new NameValuePair("client_id", storedClientId),
+ new NameValuePair("grant_type", "authorization_code"),
+ new NameValuePair("code", authorizationCode)));
webClient.getOptions().setJavaScriptEnabled(false);
final UnexpectedPage responsePage = webClient.getPage(request);
@@ -935,11 +932,11 @@
- private static WebClient setupWebClient(String user, String password, String idpPort) {
+ private static WebClient setupWebClient(String user, String password) {
final WebClient webClient = new WebClient();
webClient.getOptions().setUseInsecureSSL(true);
webClient.getCredentialsProvider().setCredentials(
- new AuthScope("localhost", Integer.parseInt(idpPort)),
+ new AuthScope("localhost", IDP_HTTPS_PORT),
new UsernamePasswordCredentials(user, password));
webClient.getOptions().setJavaScriptEnabled(false);
@@ -993,21 +990,8 @@
&& wresult.contains("urn:oasis:names:tc:SAML:2.0:cm:bearer"));
final HtmlForm form = idpPage.getFormByName("signinresponseform");
- final HtmlSubmitInput button = form.getInputByName("_eventId_submit");
-
- // Bit of a hack here to get the authorization code - necessary as HtmlUnit tries
- // to follow the server redirect to "https://127.0.0.1" - the redirect URI
- CodeWebConnectionWrapper wrapper = new CodeWebConnectionWrapper(webClient);
-
- try {
- button.click();
- // fail(); // passed for testBadClientId and testEmptyClientId
- } catch (RuntimeException e) {
- // expected
- }
-
- wrapper.close();
- return wrapper.getCode();
+ Page page = form.getInputByName("_eventId_submit").click();
+ return page.getWebResponse().getContentAsString();
}
private static String getIdToken(String parentString) {
@@ -1055,36 +1039,15 @@
SignatureAlgorithm.RS256));
}
- private static class CodeWebConnectionWrapper extends WebConnectionWrapper {
-
- private String code;
-
- CodeWebConnectionWrapper(WebClient webClient) {
- super(webClient);
- }
-
- public WebResponse getResponse(WebRequest request) throws IOException {
- WebResponse response = super.getResponse(request);
- String location = response.getResponseHeaderValue("Location");
- if (location != null && location.contains("code=")) {
- code = getSubstring(location, "code");
+ @SuppressWarnings("serial")
+ public static class CallbackServlet extends GenericServlet {
+ @Override
+ public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
+ final String code = req.getParameter("code");
+ if (null != code) {
+ res.getOutputStream().write(code.getBytes());
}
-
- return response;
- }
-
- public String getCode() {
- return code;
- }
-
- private String getSubstring(String parentString, String substringName) {
- String foundString =
- parentString.substring(parentString.indexOf(substringName + "=") + (substringName + "=").length());
- int ampersandIndex = foundString.indexOf('&');
- if (ampersandIndex < 1) {
- ampersandIndex = foundString.length();
- }
- return foundString.substring(0, ampersandIndex);
}
}
+
}
diff --git a/systests/oidc/src/test/resources/oidc/applicationContext.xml b/systests/oidc/src/test/resources/oidc/applicationContext.xml
index 9d6935a..c22a4e6 100644
--- a/systests/oidc/src/test/resources/oidc/applicationContext.xml
+++ b/systests/oidc/src/test/resources/oidc/applicationContext.xml
@@ -220,11 +220,11 @@
<bean id="refreshTokenHandler" class="org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrantHandler">
<property name="dataProvider" ref="oauthProvider"/>
</bean>
-
+
<bean id="clientCredsHandler" class="org.apache.cxf.rs.security.oauth2.grants.clientcred.ClientCredentialsGrantHandler">
<property name="dataProvider" ref="oauthProvider"/>
</bean>
-
+
<util:list id="grantHandlers">
<ref bean="refreshTokenHandler"/>
<!-- Add more custom grant handlers as needed -->
@@ -280,6 +280,6 @@
</sec:trustManagers>
</http:tlsClientParameters>
</http:conduit>
-
+
</beans>
diff --git a/systests/oidc/src/test/resources/oidc/data-manager.xml b/systests/oidc/src/test/resources/oidc/data-manager.xml
index e704818..2966b9b 100644
--- a/systests/oidc/src/test/resources/oidc/data-manager.xml
+++ b/systests/oidc/src/test/resources/oidc/data-manager.xml
@@ -90,12 +90,12 @@
<property name="authenticationStrategy" ref="authenticationStrategy"/>
</bean>
- <!-- Custom SubjectCreator where IdToken is created -->
+ <!-- Custom SubjectCreator where IdToken is created -->
<bean id="subjectCreator" class="org.apache.cxf.fediz.service.oidc.FedizSubjectCreator">
<property name="idTokenIssuer" value="accounts.fediz.com"/>
<!-- List of additional claims which can be optionally added to IdToken -->
<property name="supportedClaims" ref="supportedClaims"/>
</bean>
-
+
</beans>
diff --git a/systests/oidc/src/test/resources/oidc/spring/applicationContext.xml b/systests/oidc/src/test/resources/oidc/spring/applicationContext.xml
index 574f138..2733334 100644
--- a/systests/oidc/src/test/resources/oidc/spring/applicationContext.xml
+++ b/systests/oidc/src/test/resources/oidc/spring/applicationContext.xml
@@ -287,11 +287,11 @@
<bean id="refreshTokenHandler" class="org.apache.cxf.rs.security.oauth2.grants.refresh.RefreshTokenGrantHandler">
<property name="dataProvider" ref="oauthProvider"/>
</bean>
-
+
<bean id="clientCredsHandler" class="org.apache.cxf.rs.security.oauth2.grants.clientcred.ClientCredentialsGrantHandler">
<property name="dataProvider" ref="oauthProvider"/>
</bean>
-
+
<util:list id="grantHandlers">
<ref bean="refreshTokenHandler"/>
<!-- Add more custom grant handlers as needed -->
@@ -347,6 +347,6 @@
</sec:trustManagers>
</http:tlsClientParameters>
</http:conduit>
-
+
</beans>