From commits-return-48694-archive-asf-public=cust-asf.ponee.io@cxf.apache.org Thu Feb 22 14:05:43 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 5234018064E for ; Thu, 22 Feb 2018 14:05:42 +0100 (CET) Received: (qmail 82066 invoked by uid 500); 22 Feb 2018 13:05:41 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 82057 invoked by uid 99); 22 Feb 2018 13:05:41 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 22 Feb 2018 13:05:41 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 1E5CC85C18; Thu, 22 Feb 2018 13:05:40 +0000 (UTC) Date: Thu, 22 Feb 2018 13:05:40 +0000 To: "commits@cxf.apache.org" Subject: [cxf] branch master updated: Adding OAuth 2.0 ClientCodeRequestFilter test MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <151930474003.24865.13824764381852193559@gitbox.apache.org> From: coheigea@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: cxf X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 5d6244267c2b057fe27f59394303be284d1e5d4c X-Git-Newrev: c8dcde0b5811ce608fd98269d9e5efa2580f397b X-Git-Rev: c8dcde0b5811ce608fd98269d9e5efa2580f397b X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/cxf.git The following commit(s) were added to refs/heads/master by this push: new c8dcde0 Adding OAuth 2.0 ClientCodeRequestFilter test c8dcde0 is described below commit c8dcde0b5811ce608fd98269d9e5efa2580f397b Author: Colm O hEigeartaigh AuthorDate: Thu Feb 22 13:05:07 2018 +0000 Adding OAuth 2.0 ClientCodeRequestFilter test --- .../security/oauth2/common/OAuth2TestUtils.java | 1 + .../oauth2/common/OAuthDataProviderImpl.java | 18 +++- .../oauth2/common/WSS4JBasicAuthFilter.java | 5 + .../security/oauth2/filters/OAuth2FiltersTest.java | 90 ++++++++++++++++ .../security/oauth2/filters/PartnerServer.java | 49 +++++++++ .../security/oauth2/filters/PartnerService.java | 73 +++++++++++++ .../security/oauth2/filters/oauth20-server.xml | 1 + .../{oauth20-server.xml => partner-service.xml} | 116 ++++++++++----------- 8 files changed, 289 insertions(+), 64 deletions(-) diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuth2TestUtils.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuth2TestUtils.java index b41bf18..a19a75f 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuth2TestUtils.java +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuth2TestUtils.java @@ -153,6 +153,7 @@ public final class OAuth2TestUtils { if (audience != null) { form.param("audience", audience); } + form.param("redirect_uri", "http://www.blah.apache.org"); Response response = client.post(form); return response.readEntity(ClientAccessToken.class); diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuthDataProviderImpl.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuthDataProviderImpl.java index 9167559..67389ec 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuthDataProviderImpl.java +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/OAuthDataProviderImpl.java @@ -41,10 +41,20 @@ import org.apache.xml.security.utils.ClassLoaderUtils; */ public class OAuthDataProviderImpl extends DefaultEHCacheCodeDataProvider { private Set externalClients = new HashSet<>(); + public OAuthDataProviderImpl(String servicePort) throws Exception { + this(servicePort, null); + } + + public OAuthDataProviderImpl(String servicePort, String partnerPort) throws Exception { // filters/grants test client Client client = new Client("consumer-id", "this-is-a-secret", true); - client.setRedirectUris(Collections.singletonList("http://www.blah.apache.org")); + List redirectUris = new ArrayList<>(); + redirectUris.add("http://www.blah.apache.org"); + if (partnerPort != null) { + redirectUris.add("https://localhost:" + partnerPort + "/partnerservice/bookstore/books"); + } + client.setRedirectUris(redirectUris); client.getAllowedGrantTypes().add("authorization_code"); client.getAllowedGrantTypes().add("refresh_token"); @@ -110,15 +120,15 @@ public class OAuthDataProviderImpl extends DefaultEHCacheCodeDataProvider { client.getAllowedGrantTypes().add("urn:ietf:params:oauth:grant-type:jwt-bearer"); client.getAllowedGrantTypes().add("custom_grant"); this.setClient(client); - + client = new Client("fredNoPassword", null, true); client.getAllowedGrantTypes().add("custom_grant"); this.setClient(client); - + client = new Client("fredPublic", null, false); client.getAllowedGrantTypes().add("custom_grant"); this.setClient(client); - + client = new Client("fred", "password", true); client.getAllowedGrantTypes().add("custom_grant"); this.setClient(client); diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/WSS4JBasicAuthFilter.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/WSS4JBasicAuthFilter.java index 6db5cce..846daa3 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/WSS4JBasicAuthFilter.java +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/common/WSS4JBasicAuthFilter.java @@ -20,8 +20,11 @@ package org.apache.cxf.systest.jaxrs.security.oauth2.common; import java.io.IOException; +import javax.annotation.Priority; +import javax.ws.rs.Priorities; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; import javax.ws.rs.core.Response; import org.apache.cxf.configuration.security.AuthorizationPolicy; @@ -33,6 +36,8 @@ import org.apache.cxf.rt.security.saml.interceptor.WSS4JBasicAuthValidator; /** * Extends the WSS4J validator as a JAX-RS request filter */ +@PreMatching +@Priority(Priorities.AUTHENTICATION) public class WSS4JBasicAuthFilter extends WSS4JBasicAuthValidator implements ContainerRequestFilter { public void filter(ContainerRequestContext requestContext) throws IOException { diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/OAuth2FiltersTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/OAuth2FiltersTest.java index d04a293..0b62965 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/OAuth2FiltersTest.java +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/OAuth2FiltersTest.java @@ -22,10 +22,12 @@ package org.apache.cxf.systest.jaxrs.security.oauth2.filters; import java.net.URL; import java.util.UUID; +import javax.ws.rs.core.Form; import javax.ws.rs.core.Response; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken; +import org.apache.cxf.rs.security.oauth2.common.OAuthAuthorizationData; import org.apache.cxf.systest.jaxrs.security.Book; import org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuth2TestUtils; import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase; @@ -38,6 +40,7 @@ import org.junit.BeforeClass; public class OAuth2FiltersTest extends AbstractBusClientServerTestBase { public static final String PORT = BookServerOAuth2Filters.PORT; public static final String OAUTH_PORT = BookServerOAuth2Service.PORT; + public static final String PARTNER_PORT = PartnerServer.PORT; @BeforeClass public static void startServers() throws Exception { @@ -45,6 +48,8 @@ public class OAuth2FiltersTest extends AbstractBusClientServerTestBase { launchServer(BookServerOAuth2Filters.class, true)); assertTrue("server did not launch correctly", launchServer(BookServerOAuth2Service.class, true)); + assertTrue("server did not launch correctly", + launchServer(PartnerServer.class, true)); } @org.junit.Test @@ -368,4 +373,89 @@ public class OAuth2FiltersTest extends AbstractBusClientServerTestBase { assertNotEquals(response.getStatus(), 200); } + @org.junit.Test + public void testPartnerServiceUsingClientCodeRequestFilter() throws Exception { + URL busFile = OAuth2FiltersTest.class.getResource("client.xml"); + + // Invoke on the partner service, which is secured with the ClientCodeRequestFilter + String partnerService = "https://localhost:" + PARTNER_PORT + "/partnerservice/bookstore/books"; + + WebClient partnerClient = + WebClient.create(partnerService, OAuth2TestUtils.setupProviders(), "bob", "security", busFile.toString()); + // Save the Cookie for the second request... + WebClient.getConfig(partnerClient).getRequestContext().put( + org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE); + + Response response = partnerClient.type("application/xml").post(new Book("book", 123L)); + + // Response response = partnerClient.get(); + // Get the "Location" + String location = response.getHeaderString("Location"); + // Now make an invocation on the OIDC IdP using another WebClient instance + + + WebClient idpClient = + WebClient.create(location, OAuth2TestUtils.setupProviders(), "bob", "security", busFile.toString()); + // Save the Cookie for the second request... + WebClient.getConfig(idpClient).getRequestContext().put( + org.apache.cxf.message.Message.MAINTAIN_SESSION, Boolean.TRUE); + + // Get Authorization Code + State + String receivedLocation = getLocationUsingAuthorizationCodeGrant(idpClient); + assertNotNull(receivedLocation); + String code = getSubstring(receivedLocation, "code"); + String state = getSubstring(receivedLocation, "state"); + + // Add Referer + String referer = "https://localhost:" + OAUTH_PORT + "/services/authorize"; + partnerClient.header("Referer", referer); + + // Now invoke back on the service using the authorization code + partnerClient.query("code", code); + partnerClient.query("state", state); + + Response serviceResponse = partnerClient.accept("application/xml").post(new Book("book", 123L)); + assertEquals(serviceResponse.getStatus(), 200); + Book returnedBook = serviceResponse.readEntity(Book.class); + assertEquals(returnedBook.getName(), "book"); + assertEquals(returnedBook.getId(), 123L); + } + + private String getLocationUsingAuthorizationCodeGrant(WebClient client) { + client.type("application/json").accept("application/json"); + + Response response = client.get(); + + OAuthAuthorizationData authzData = response.readEntity(OAuthAuthorizationData.class); + + // Now call "decision" to get the authorization code grant + client.path("decision"); + client.type("application/x-www-form-urlencoded"); + + Form form = new Form(); + form.param("session_authenticity_token", authzData.getAuthenticityToken()); + form.param("client_id", authzData.getClientId()); + form.param("redirect_uri", authzData.getRedirectUri()); + if (authzData.getProposedScope() != null) { + form.param("scope", authzData.getProposedScope()); + } + form.param("state", authzData.getState()); + form.param("oauthDecision", "allow"); + + response = client.post(form); + return response.getHeaderString("Location"); + } + + + 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/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/PartnerServer.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/PartnerServer.java new file mode 100644 index 0000000..c838954 --- /dev/null +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/PartnerServer.java @@ -0,0 +1,49 @@ +/** + * 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.oauth2.filters; + +import java.net.URL; + +import org.apache.cxf.Bus; +import org.apache.cxf.BusFactory; +import org.apache.cxf.bus.spring.SpringBusFactory; +import org.apache.cxf.testutil.common.AbstractBusTestServerBase; +import org.apache.cxf.testutil.common.TestUtil; + +public class PartnerServer extends AbstractBusTestServerBase { + + public static final String PORT = TestUtil.getPortNumber("jaxrs-oauth2-filters-partner"); + + public PartnerServer() { + + } + + protected void run() { + URL busFile = PartnerServer.class.getResource("partner-service.xml"); + Bus busLocal = new SpringBusFactory().createBus(busFile); + BusFactory.setDefaultBus(busLocal); + setBus(busLocal); + + try { + new PartnerServer(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/PartnerService.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/PartnerService.java new file mode 100644 index 0000000..7e1954b --- /dev/null +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/oauth2/filters/PartnerService.java @@ -0,0 +1,73 @@ +/** + * 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.oauth2.filters; + + +import java.net.URL; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +import org.apache.cxf.jaxrs.client.WebClient; +import org.apache.cxf.rs.security.oauth2.client.ClientTokenContext; +import org.apache.cxf.systest.jaxrs.security.Book; + +/** + * A "Partner" service that delegates an "echoBook" call to the BookStore, first getting an OAuth token using the + * ClientCodeRequestFilter. + */ +@Path("/bookstore") +public class PartnerService { + + @Context + private ClientTokenContext context; + + + @POST + @Path("/books") + @Produces("application/xml") + @Consumes("application/xml") + public Book echoBookXml(Book book) { + + URL busFile = PartnerService.class.getResource("client.xml"); + + String address = "https://localhost:" + OAuth2FiltersTest.PORT + "/secured/bookstore/books"; + WebClient client = WebClient.create(address, busFile.toString()); + + client.type("application/xml").accept("application/xml"); + + client.header("Authorization", "Bearer " + context.getToken().getTokenKey()); + + // Now make a service invocation with the access token + Response serviceResponse = client.post(book); + if (serviceResponse.getStatus() == 200) { + return serviceResponse.readEntity(Book.class); + } + + throw new WebApplicationException(Response.Status.FORBIDDEN); + } + +} + diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/oauth20-server.xml b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/oauth20-server.xml index 16ab0be..a5f8d72 100644 --- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/oauth20-server.xml +++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/oauth20-server.xml @@ -64,6 +64,7 @@ under the License. ${testutil.ports.jaxrs-oauth2-filters} + ${testutil.ports.jaxrs-oauth2-filters-partner} diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/oauth20-server.xml b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/partner-service.xml similarity index 58% copy from systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/oauth20-server.xml copy to systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/partner-service.xml index 16ab0be..d01228b 100644 --- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/oauth20-server.xml +++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/oauth2/filters/partner-service.xml @@ -23,9 +23,11 @@ under the License. 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:jaxrs="http://cxf.apache.org/jaxrs" + xmlns:jaxrs-client="http://cxf.apache.org/jaxrs-client" 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/jaxrs-client http://cxf.apache.org/schemas/jaxrs-client.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-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd @@ -37,18 +39,61 @@ under the License. - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -56,59 +101,10 @@ under the License. - + true - - - ${testutil.ports.jaxrs-oauth2-filters} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- To stop receiving notification emails like this one, please contact coheigea@apache.org.