Repository: cxf Updated Branches: refs/heads/master 49829a180 -> 2345b6e4f
[CXF-6490] Prototyping basic_oidc demo Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/2345b6e4 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/2345b6e4 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/2345b6e4 Branch: refs/heads/master Commit: 2345b6e4ff4adf48e9adf5e0b9245da3f7afa011 Parents: 49829a1 Author: Sergey Beryozkin <sberyoz...@talend.com> Authored: Thu Jul 16 17:42:53 2015 +0300 Committer: Sergey Beryozkin <sberyoz...@talend.com> Committed: Thu Jul 16 17:42:53 2015 +0300 ---------------------------------------------------------------------- .../samples/jax_rs/basic_oidc/README.txt | 5 + .../release/samples/jax_rs/basic_oidc/pom.xml | 115 ++++++++++++++++++ .../java/demo/jaxrs/server/IdTokenService.java | 45 +++++++ .../main/webapp/WEB-INF/applicationContext.xml | 119 +++++++++++++++++++ .../src/main/webapp/WEB-INF/servicestore.jks | Bin 0 -> 3350 bytes .../basic_oidc/src/main/webapp/WEB-INF/web.xml | 33 +++++ .../src/main/webapp/forms/idToken.jsp | 32 +++++ .../src/main/webapp/forms/oidcClientContext.jsp | 14 +++ .../basic_oidc/src/main/webapp/simpleLogin.html | 39 ++++++ 9 files changed, 402 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/2345b6e4/distribution/src/main/release/samples/jax_rs/basic_oidc/README.txt ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/README.txt b/distribution/src/main/release/samples/jax_rs/basic_oidc/README.txt new file mode 100644 index 0000000..d364206 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/basic_oidc/README.txt @@ -0,0 +1,5 @@ +JAX-RS Basic OpenId Connect Demo +================================ + +This demo demonstrates how to authenticate a user with OpenId Connect. + http://git-wip-us.apache.org/repos/asf/cxf/blob/2345b6e4/distribution/src/main/release/samples/jax_rs/basic_oidc/pom.xml ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/pom.xml b/distribution/src/main/release/samples/jax_rs/basic_oidc/pom.xml new file mode 100644 index 0000000..fa2b1c5 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/basic_oidc/pom.xml @@ -0,0 +1,115 @@ +<?xml version="1.0"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>jax_rs_basic_oidc</artifactId> + <name>JAX-RS Basic Oidc Demo</name> + <description>JAX-RS Basic Oidc Demo</description> + <packaging>war</packaging> + <parent> + <groupId>org.apache.cxf.samples</groupId> + <artifactId>cxf-samples</artifactId> + <version>3.1.2-SNAPSHOT</version> + <relativePath>../..</relativePath> + </parent> + <properties> + </properties> + <dependencies> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-http</artifactId> + <version>3.1.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + <version>3.1.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-security-jose</artifactId> + <version>3.1.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-security-sso-oidc</artifactId> + <version>3.1.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + <version>4.1.1.RELEASE</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>4.1.1.RELEASE</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + <version>4.1.1.RELEASE</version> + </dependency> + </dependencies> + <build> + <!-- Name of the generated WAR file --> + <finalName>user</finalName> + <plugins> + <plugin> + <groupId>org.mortbay.jetty</groupId> + <artifactId>maven-jetty-plugin</artifactId> + <version>6.1.15</version> + <configuration> + <contextPath>/${project.build.finalName}</contextPath> + <connectors> + <connector implementation="org.mortbay.jetty.security.SslSocketConnector"> + <port>8080</port> + <keystore>${project.build.directory}/user/WEB-INF/servicestore.jks</keystore> + <password>sspass</password> + <keyPassword>skpass</keyPassword> + </connector> + </connectors> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <version>2.1.1</version> + <configuration> + <webResources> + <resource> + <directory>src/main/webapp</directory> + <filtering>true</filtering> + <includes> + <include>**/applicationContext.xml</include> + <include>**/simpleLogin.html</include> + </includes> + </resource> + </webResources> + </configuration> + </plugin> + </plugins> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/cxf/blob/2345b6e4/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/java/demo/jaxrs/server/IdTokenService.java ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/java/demo/jaxrs/server/IdTokenService.java b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/java/demo/jaxrs/server/IdTokenService.java new file mode 100644 index 0000000..2f1a313 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/java/demo/jaxrs/server/IdTokenService.java @@ -0,0 +1,45 @@ +/** + * 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 demo.jaxrs.server; + +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +import org.apache.cxf.rs.security.oidc.common.IdToken; + +@Path("/") +public class IdTokenService { + @POST + @Path("/token") + @Produces("text/html") + public Response getIdTokenFromForm(@Context IdToken idToken) { + return getIdToken(idToken); + } + + @GET + @Path("/token") + @Produces("text/html") + public Response getIdToken(@Context IdToken idToken) { + return Response.ok(idToken).build(); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/2345b6e4/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/applicationContext.xml ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/applicationContext.xml b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/applicationContext.xml new file mode 100644 index 0000000..3fa9454 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/applicationContext.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2011 Talend Inc. - www.talend.com +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:jaxrs="http://cxf.apache.org/jaxrs" + xmlns:jaxrsclient="http://cxf.apache.org/jaxrs-client" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-2.0.xsd + 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"> + + <!-- CXF Logging Feature --> + <bean id="loggingFeature" class="org.apache.cxf.feature.LoggingFeature"/> + + <bean id="idTokenService" class="demo.jaxrs.server.IdTokenService"/> + <jaxrs:server id="idTokenServer" address="/info"> + <jaxrs:serviceBeans> + <ref bean="idTokenService"/> + </jaxrs:serviceBeans> + <jaxrs:providers> + <!-- Checks that a client is authenticated with Google --> + <ref bean="oidcRpFilter"/> + + <ref bean="searchView"/> + + <!-- JAX-RS provider that makes IdToken available as JAX-RS @Context --> + <ref bean="oidcIdTokenProvider"/> + </jaxrs:providers> + <jaxrs:features> + <ref bean="loggingFeature"/> + </jaxrs:features> + </jaxrs:server> + + <!-- JAX-RS provider that makes IdToken available as JAX-RS @Context --> + <bean id="oidcIdTokenProvider" class="org.apache.cxf.rs.security.oidc.rp.OidcIdTokenProvider"/> + + <bean id="oidcRpFilter" class="org.apache.cxf.rs.security.oidc.rp.OidcRpAuthenticationFilter"> + <!-- + This state manager is shared between this filter and the RP endpoint, + the RP endpoint sets an OIDC context on it and this filter checks the context is available + --> + <property name="stateManager" ref="stateManager"/> + </bean> + + <bean id="searchView" class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider"> + <property name="useClassNames" value="true"/> + <property name="locationPrefix" value="/forms/"/> + <property name="beanName" value="data"/> + </bean> + + <!-- + 2. OIDC RP endpoint: authenticates a user by redirecting a user to Google, and redirects the user + to the initial application form once the authentication is done + --> + <jaxrs:server id="oidcRpServer" address="/oidc"> + <jaxrs:serviceBeans> + <ref bean="oidcRpService"/> + </jaxrs:serviceBeans> + <jaxrs:providers> + <!-- the filter which does the actual work for obtaining an OIDC context --> + <ref bean="oidcIdTokenFilter"/> + <ref bean="searchView"/> + <!-- JAX-RS provider that makes OidcClientTokenContext available as JAX-RS @Context --> + <ref bean="oidcIdTokenProvider"/> + </jaxrs:providers> + <jaxrs:features> + <ref bean="loggingFeature"/> + </jaxrs:features> + </jaxrs:server> + + <bean id="oidcRpService" class="org.apache.cxf.rs.security.oidc.rp.OidcRpAuthenticationService"> + <!-- This state manager is shared between this RP endpoint and the oidcRpFilter which protects + the application endpoint, the RP endpoint sets an OIDC context on it and the filter checks + the context is available --> + <property name="stateManager" ref="stateManager"/> + </bean> + <!-- The state manager shared between the RP and application endpoints --> + <bean id="stateManager" class="org.apache.cxf.rs.security.oauth2.client.MemoryClientTokenContextManager"/> + + <!-- This RP filter reads OIDC IdToken --> + <bean id="oidcIdTokenFilter" class="org.apache.cxf.rs.security.oidc.rp.OidcIdTokenRequestFilter"> + <property name="idTokenReader" ref="idTokenReader"/> + <property name="consumer" ref="consumer"/> + <property name="tokenFormParameter" value="idtoken"/> + </bean> + + <!-- The RP filter uses this reader to read and validate OIDC IdToken --> + <bean id="idTokenReader" class="org.apache.cxf.rs.security.oidc.rp.IdTokenReader"> + <property name="jwkSetClient" ref="jwkSetClient"/> + <property name="issuerId" value="accounts.google.com"/> + <property name="clockOffset" value="10"/> + </bean> + + <!-- WebClient for requesting an OIDC IDP JWK Set + This client is used to get a JWK key required to validate OIDC IdToken returned with the OAuth2 access token --> + <jaxrsclient:client id="jwkSetClient" threadSafe="true" + address="https://www.googleapis.com/oauth2/v2/certs" + serviceClass="org.apache.cxf.jaxrs.client.WebClient"> + <jaxrsclient:headers> + <entry key="Accept" value="application/json"/> + </jaxrsclient:headers> + <jaxrsclient:providers> + <bean class="org.apache.cxf.rs.security.jose.jaxrs.JsonWebKeysProvider"/> + </jaxrsclient:providers> + <jaxrsclient:features> + <ref bean="loggingFeature"/> + </jaxrsclient:features> + </jaxrsclient:client> + <bean id="consumer" class="org.apache.cxf.rs.security.oauth2.client.Consumer"> + <property name="key" value="${client_id}"/> + </bean> + +</beans> + http://git-wip-us.apache.org/repos/asf/cxf/blob/2345b6e4/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/servicestore.jks ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/servicestore.jks b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/servicestore.jks new file mode 100644 index 0000000..0dfa206 Binary files /dev/null and b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/servicestore.jks differ http://git-wip-us.apache.org/repos/asf/cxf/blob/2345b6e4/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/web.xml b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..9790ce7 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2011 Talend Inc. - www.talend.com +--> +<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/j2ee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee + http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> + <display-name>Advanced JAX-RS Web Application</display-name> + <listener> + <listener-class> + org.springframework.web.context.ContextLoaderListener + </listener-class> + </listener> + <context-param> + <param-name>contextConfigLocation</param-name> + <param-value> + WEB-INF/applicationContext.xml + </param-value> + </context-param> + <servlet> + <servlet-name>RESTServlet</servlet-name> + <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> + <load-on-startup>1</load-on-startup> + </servlet> + <servlet-mapping> + <servlet-name>RESTServlet</servlet-name> + <url-pattern>/service/*</url-pattern> + </servlet-mapping> + <session-config> + <session-timeout>60</session-timeout> + </session-config> +</web-app> http://git-wip-us.apache.org/repos/asf/cxf/blob/2345b6e4/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/forms/idToken.jsp ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/forms/idToken.jsp b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/forms/idToken.jsp new file mode 100644 index 0000000..5287de7 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/forms/idToken.jsp @@ -0,0 +1,32 @@ +<%@ page import="javax.servlet.http.HttpServletRequest, org.apache.cxf.rs.security.oidc.common.IdToken" %> + +<% + IdToken token = (IdToken) request.getAttribute("data"); +%> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>IdToken</title> + <STYLE TYPE="text/css"> + <!-- + input {font-family:verdana, arial, helvetica, sans-serif;font-size:20px;line-height:40px;} + div.padded { + padding-left: 5em; + } + --> +</STYLE> +</head> +<body> +<div class="padded"> +<h1>Id Token Details</h1> +<em></em> +<p> +<table border="1"> + <tr><th><big><big>Property</big></big></th><th><big><big>Value</big></big></th></tr> + <tr> + <td><big>Email</big></big></td> + <td><big><big><%= token.getClaim("email") %></big></big></td> + </tr> +</table> +</div> +</body> +</html> http://git-wip-us.apache.org/repos/asf/cxf/blob/2345b6e4/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/forms/oidcClientContext.jsp ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/forms/oidcClientContext.jsp b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/forms/oidcClientContext.jsp new file mode 100644 index 0000000..e07d044 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/forms/oidcClientContext.jsp @@ -0,0 +1,14 @@ +<%@ page import="javax.servlet.http.HttpServletRequest, org.apache.cxf.rs.security.oidc.rp.OidcClientTokenContext" %> + +<% + OidcClientTokenContext oidc = (OidcClientTokenContext) request.getAttribute("data"); + String basePath = request.getContextPath() + request.getServletPath(); + if (!basePath.endsWith("/")) { + basePath += "/"; + } +%> +<html xmlns="http://www.w3.org/1999/xhtml"> +<div class="padded"> +</div> +</body> +</html> http://git-wip-us.apache.org/repos/asf/cxf/blob/2345b6e4/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/simpleLogin.html ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/simpleLogin.html b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/simpleLogin.html new file mode 100644 index 0000000..01f39ce --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/basic_oidc/src/main/webapp/simpleLogin.html @@ -0,0 +1,39 @@ +<html lang="en"> + <head> + <title>Welcome to IdTokenService</title> + <STYLE TYPE="text/css"> + <!-- + input {font-family:verdana, arial, helvetica, sans-serif;font-size:20px;line-height:40px;} + div.padded { + padding-left: 5em; + } + --> + </STYLE> + <meta name="google-signin-scope" content="profile email"> + <meta name="google-signin-client_id" content="${client_id}"> + <script src="https://apis.google.com/js/platform.js" async defer></script> + </head> + <body> + <div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div> + <script> + function onSignIn(googleUser) { + var id_token = googleUser.getAuthResponse().id_token; + var xhr = new XMLHttpRequest(); + xhr.onload = function() { + + } + xhr.open('POST', 'https://localhost:8080/user/service/oidc/rp/signin'); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.send('idtoken=' + id_token); + }; + </script> + <div class="padded"> +<h1>Welcome to IdToken Service</h1> +<em/> +<p/> + <form action="https://localhost:8080/user/service/info/token" method="POST"> + <input type="submit" value="Display IdToken Properties"/> + </form> +</div> + </body> +</html> \ No newline at end of file