You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2017/09/27 02:18:08 UTC

[16/29] incubator-guacamole-client git commit: GUACAMOLE-210: Migrate to implicit flow (client-side, relies on "id_token"). Update to pre-release 0.9.9-incubating codebase.

GUACAMOLE-210: Migrate to implicit flow (client-side, relies on "id_token"). Update to pre-release 0.9.9-incubating codebase.


Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/fdc03133
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/fdc03133
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/fdc03133

Branch: refs/heads/master
Commit: fdc031338722242e30d1ca0b2e393a4b2ae2e8f0
Parents: c3c6e0c
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Jun 12 00:14:00 2016 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon Sep 25 13:06:43 2017 -0700

----------------------------------------------------------------------
 extensions/guacamole-auth-openid/pom.xml        |  18 +--
 .../oauth/AuthenticationProviderService.java    |  46 ++----
 .../auth/oauth/OAuthAuthenticationProvider.java |  10 +-
 .../OAuthAuthenticationProviderModule.java      |  33 +---
 .../auth/oauth/conf/ConfigurationService.java   |  38 +----
 .../oauth/conf/OAuthGuacamoleProperties.java    |  26 +---
 .../auth/oauth/form/OAuthCodeField.java         |  97 ------------
 .../auth/oauth/form/OAuthTokenField.java        | 100 ++++++++++++
 .../auth/oauth/token/TokenResponse.java         | 153 -------------------
 .../auth/oauth/token/TokenService.java          | 101 ------------
 .../auth/oauth/user/AuthenticatedUser.java      |   6 +-
 .../src/main/resources/guac-manifest.json       |   9 +-
 .../src/main/resources/oauthCodeField.html      |   1 -
 .../src/main/resources/oauthConfig.js           |  29 +++-
 .../src/main/resources/oauthController.js       |  30 ++++
 15 files changed, 192 insertions(+), 505 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/pom.xml
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/pom.xml b/extensions/guacamole-auth-openid/pom.xml
index d443cdd..60691e2 100644
--- a/extensions/guacamole-auth-openid/pom.xml
+++ b/extensions/guacamole-auth-openid/pom.xml
@@ -26,7 +26,7 @@
     <groupId>org.apache.guacamole</groupId>
     <artifactId>guacamole-auth-openid</artifactId>
     <packaging>jar</packaging>
-    <version>0.9.9</version>
+    <version>0.9.9-incubating</version>
     <name>guacamole-auth-openid</name>
     <url>http://guacamole.incubator.apache.org/</url>
 
@@ -80,24 +80,12 @@
 
         <!-- Guacamole Extension API -->
         <dependency>
-            <groupId>org.glyptodon.guacamole</groupId>
+            <groupId>org.apache.guacamole</groupId>
             <artifactId>guacamole-ext</artifactId>
-            <version>0.9.9</version>
+            <version>0.9.9-incubating</version>
             <scope>provided</scope>
         </dependency>
 
-        <!-- Jersey Client -->
-        <dependency>
-            <groupId>com.sun.jersey</groupId>
-            <artifactId>jersey-client</artifactId>
-            <version>1.17.1</version>
-        </dependency>
-        <dependency>
-            <groupId>com.sun.jersey</groupId>
-            <artifactId>jersey-json</artifactId>
-            <version>1.17.1</version>
-        </dependency>
-
         <!-- Guice -->
         <dependency>
             <groupId>com.google.inject</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java
index 5783faa..0aac968 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/AuthenticationProviderService.java
@@ -25,14 +25,12 @@ import java.util.Arrays;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.guacamole.auth.oauth.user.AuthenticatedUser;
 import org.apache.guacamole.auth.oauth.conf.ConfigurationService;
-import org.apache.guacamole.auth.oauth.form.OAuthCodeField;
-import org.apache.guacamole.auth.oauth.token.TokenResponse;
-import org.apache.guacamole.auth.oauth.token.TokenService;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.form.Field;
-import org.glyptodon.guacamole.net.auth.Credentials;
-import org.glyptodon.guacamole.net.auth.credentials.CredentialsInfo;
-import org.glyptodon.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
+import org.apache.guacamole.auth.oauth.form.OAuthTokenField;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.form.Field;
+import org.apache.guacamole.net.auth.Credentials;
+import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
+import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,12 +52,6 @@ public class AuthenticationProviderService {
     private ConfigurationService confService;
 
     /**
-     * Service for producing authentication tokens from OAuth codes.
-     */
-    @Inject
-    private TokenService tokenService;
-
-    /**
      * Provider for AuthenticatedUser objects.
      */
     @Inject
@@ -83,19 +75,15 @@ public class AuthenticationProviderService {
     public AuthenticatedUser authenticateUser(Credentials credentials)
             throws GuacamoleException {
 
-        String code = null;
+        String token = null;
 
-        // Pull OAuth code from request if present
+        // Pull OAuth token from request if present
         HttpServletRequest request = credentials.getRequest();
         if (request != null)
-            code = request.getParameter(OAuthCodeField.PARAMETER_NAME);
-
-        // TODO: Actually complete authentication using received code
-        if (code != null) {
+            token = request.getParameter(OAuthTokenField.PARAMETER_NAME);
 
-            // POST code and client information to OAuth token endpoint
-            TokenResponse response = tokenService.getTokenFromCode(code);
-            logger.debug("RESPONSE: {}", response);
+        // TODO: Actually validate received token
+        if (token != null) {
 
             // Create corresponding authenticated user
             AuthenticatedUser authenticatedUser = authenticatedUserProvider.get();
@@ -104,17 +92,13 @@ public class AuthenticationProviderService {
 
         }
 
-        // Request auth code
+        // Request OAuth token
         throw new GuacamoleInvalidCredentialsException("Invalid login.",
             new CredentialsInfo(Arrays.asList(new Field[] {
 
-                // Normal username/password fields
-                CredentialsInfo.USERNAME,
-                CredentialsInfo.PASSWORD,
-
-                // OAuth-specific code (will be rendered as an appropriate
-                // "Log in with..." button
-                new OAuthCodeField(
+                // OAuth-specific token (will automatically redirect the user
+                // to the authorization page via JavaScript)
+                new OAuthTokenField(
                     confService.getAuthorizationEndpoint(),
                     confService.getClientID(),
                     confService.getRedirectURI()

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java
index 06255ac..6ede890 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProvider.java
@@ -21,11 +21,11 @@ package org.apache.guacamole.auth.oauth;
 
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.net.auth.AuthenticatedUser;
-import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
-import org.glyptodon.guacamole.net.auth.Credentials;
-import org.glyptodon.guacamole.net.auth.UserContext;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.net.auth.AuthenticatedUser;
+import org.apache.guacamole.net.auth.AuthenticationProvider;
+import org.apache.guacamole.net.auth.Credentials;
+import org.apache.guacamole.net.auth.UserContext;
 
 /**
  * Guacamole authentication backend which authenticates users using an

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java
index a5cef6d..202e6a2 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/OAuthAuthenticationProviderModule.java
@@ -20,17 +20,11 @@
 package org.apache.guacamole.auth.oauth;
 
 import com.google.inject.AbstractModule;
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.config.ClientConfig;
-import com.sun.jersey.api.client.config.DefaultClientConfig;
 import org.apache.guacamole.auth.oauth.conf.ConfigurationService;
-import org.apache.guacamole.auth.oauth.token.TokenService;
-import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
-import org.codehaus.jackson.map.DeserializationConfig;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.environment.Environment;
-import org.glyptodon.guacamole.environment.LocalEnvironment;
-import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.environment.Environment;
+import org.apache.guacamole.environment.LocalEnvironment;
+import org.apache.guacamole.net.auth.AuthenticationProvider;
 
 /**
  * Guice module which configures OAuth-specific injections.
@@ -49,12 +43,6 @@ public class OAuthAuthenticationProviderModule extends AbstractModule {
     private final AuthenticationProvider authProvider;
 
     /**
-     * A reference to the shared HTTP client to be used when making calls to
-     * the OAuth service.
-     */
-    private final Client client;
-
-    /**
      * Creates a new OAuth authentication provider module which configures
      * injection for the OAuthAuthenticationProvider.
      *
@@ -74,15 +62,6 @@ public class OAuthAuthenticationProviderModule extends AbstractModule {
         // Store associated auth provider
         this.authProvider = authProvider;
 
-        // Set up configuration for HTTP client
-        ClientConfig clientConfig = new DefaultClientConfig();
-        clientConfig.getSingletons().add(new JacksonJaxbJsonProvider()
-            .configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
-        );
-
-        // Store pre-configured HTTP client
-        this.client = Client.create(clientConfig);
-
     }
 
     @Override
@@ -94,10 +73,6 @@ public class OAuthAuthenticationProviderModule extends AbstractModule {
 
         // Bind OAuth-specific services
         bind(ConfigurationService.class);
-        bind(TokenService.class);
-
-        // Bind HTTP client
-        bind(Client.class).toInstance(client);
 
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java
index e1567d2..9debab7 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/ConfigurationService.java
@@ -20,8 +20,8 @@
 package org.apache.guacamole.auth.oauth.conf;
 
 import com.google.inject.Inject;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.environment.Environment;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.environment.Environment;
 
 /**
  * Service for retrieving configuration information regarding the OAuth service.
@@ -51,22 +51,6 @@ public class ConfigurationService {
     }
 
     /**
-     * Returns the token endpoint (URI) of the OAuth service as configured with
-     * guacamole.properties.
-     *
-     * @return
-     *     The token endpoint of the OAuth service, as configured with
-     *     guacamole.properties.
-     *
-     * @throws GuacamoleException
-     *     If guacamole.properties cannot be parsed, or if the authorization
-     *     endpoint property is missing.
-     */
-    public String getTokenEndpoint() throws GuacamoleException {
-        return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_TOKEN_ENDPOINT);
-    }
-
-    /**
      * Returns the OAuth client ID which should be submitted to the OAuth
      * service when necessary, as configured with guacamole.properties. This
      * value is typically provided by the OAuth service when OAuth credentials
@@ -85,24 +69,6 @@ public class ConfigurationService {
     }
 
     /**
-     * Returns the OAuth client secret which should be submitted to the OAuth
-     * service when necessary, as configured with guacamole.properties. This
-     * value is typically provided by the OAuth service when OAuth credentials
-     * are generated for your application.
-     *
-     * @return
-     *     The client secret to use when communicating with the OAuth service,
-     *     as configured with guacamole.properties.
-     *
-     * @throws GuacamoleException
-     *     If guacamole.properties cannot be parsed, or if the client secret
-     *     property is missing.
-     */
-    public String getClientSecret() throws GuacamoleException {
-        return environment.getRequiredProperty(OAuthGuacamoleProperties.OAUTH_CLIENT_SECRET);
-    }
-
-    /**
      * Returns the URI that the OAuth service should redirect to after
      * the authentication process is complete, as configured with
      * guacamole.properties. This must be the full URL that a user would enter

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java
index 0ebb94f..34952fe 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/conf/OAuthGuacamoleProperties.java
@@ -19,7 +19,7 @@
 
 package org.apache.guacamole.auth.oauth.conf;
 
-import org.glyptodon.guacamole.properties.StringGuacamoleProperty;
+import org.apache.guacamole.properties.StringGuacamoleProperty;
 
 /**
  * Provides properties required for use of the OAuth authentication provider.
@@ -45,17 +45,6 @@ public class OAuthGuacamoleProperties {
     };
 
     /**
-     * The token endpoint (URI) of the OAuth service.
-     */
-    public static final StringGuacamoleProperty OAUTH_TOKEN_ENDPOINT =
-            new StringGuacamoleProperty() {
-
-        @Override
-        public String getName() { return "oauth-token-endpoint"; }
-
-    };
-
-    /**
      * OAuth client ID which should be submitted to the OAuth service when
      * necessary. This value is typically provided by the OAuth service when
      * OAuth credentials are generated for your application.
@@ -69,19 +58,6 @@ public class OAuthGuacamoleProperties {
     };
 
     /**
-     * OAuth client secret which should be submitted to the OAuth service when
-     * necessary. This value is typically provided by the OAuth service when
-     * OAuth credentials are generated for your application.
-     */
-    public static final StringGuacamoleProperty OAUTH_CLIENT_SECRET =
-            new StringGuacamoleProperty() {
-
-        @Override
-        public String getName() { return "oauth-client-secret"; }
-
-    };
-
-    /**
      * The URI that the OAuth service should redirect to after the
      * authentication process is complete. This must be the full URL that a
      * user would enter into their browser to access Guacamole.

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java
deleted file mode 100644
index 9b0764a..0000000
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthCodeField.java
+++ /dev/null
@@ -1,97 +0,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.
- */
-
-package org.apache.guacamole.auth.oauth.form;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import org.glyptodon.guacamole.form.Field;
-
-/**
- * Field definition which represents the code returned by an OAuth service.
- * Within the user interface, this will be rendered as an appropriate "Log in
- * with ..." button which links to the OAuth service.
- */
-public class OAuthCodeField extends Field {
-
-    /**
-     * The standard HTTP parameter which will be included within the URL by all
-     * OAuth services upon successful authentication and redirect.
-     */
-    public static final String PARAMETER_NAME = "code";
-
-    /**
-     * The full URI which the field should link to.
-     */
-    private final String authorizationURI;
-
-    /**
-     * Creates a new OAuth "code" field which links to the given OAuth service
-     * using the provided client ID. Successful authentication at the OAuth
-     * service will result in the client being redirected to the specified
-     * redirect URI. The OAuth code will be embedded in the query parameters of
-     * that URI.
-     *
-     * @param authorizationEndpoint
-     *     The full URL of the endpoint accepting OAuth authentication
-     *     requests.
-     *
-     * @param clientID
-     *     The ID of the OAuth client. This is normally determined ahead of
-     *     time by the OAuth service through some manual credential request
-     *     procedure.
-     *
-     * @param redirectURI
-     *     The URI that the OAuth service should redirect to upon successful
-     *     authentication.
-     */
-    public OAuthCodeField(String authorizationEndpoint, String clientID,
-            String redirectURI) {
-
-        // Init base field properties
-        super(PARAMETER_NAME, "GUAC_OAUTH_CODE");
-
-        // Build authorization URI from given values
-        try {
-            this.authorizationURI = authorizationEndpoint
-                    + "?scope=openid%20email%20profile"
-                    + "&response_type=code"
-                    + "&client_id=" + URLEncoder.encode(clientID, "UTF-8")
-                    + "&redirect_uri=" + URLEncoder.encode(redirectURI, "UTF-8");
-        }
-
-        // Java is required to provide UTF-8 support
-        catch (UnsupportedEncodingException e) {
-            throw new UnsupportedOperationException("Unexpected lack of UTF-8 support.", e);
-        }
-
-    }
-
-    /**
-     * Returns the full URI that this field should link to when a new code
-     * needs to be obtained from the OAuth service.
-     *
-     * @return
-     *     The full URI that this field should link to.
-     */
-    public String getAuthorizationURI() {
-        return authorizationURI;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java
new file mode 100644
index 0000000..84484e5
--- /dev/null
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/form/OAuthTokenField.java
@@ -0,0 +1,100 @@
+/*
+ * 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.guacamole.auth.oauth.form;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.UUID;
+import org.apache.guacamole.form.Field;
+
+/**
+ * Field definition which represents the token returned by an OAuth service.
+ * Within the user interface, this will be rendered as an appropriate "Log in
+ * with ..." button which links to the OAuth service.
+ */
+public class OAuthTokenField extends Field {
+
+    /**
+     * The standard HTTP parameter which will be included within the URL by all
+     * OAuth services upon successful authentication and redirect.
+     */
+    public static final String PARAMETER_NAME = "id_token";
+
+    /**
+     * The full URI which the field should link to.
+     */
+    private final String authorizationURI;
+
+    /**
+     * Creates a new OAuth "id_token" field which links to the given OAuth
+     * service using the provided client ID. Successful authentication at the
+     * OAuth service will result in the client being redirected to the specified
+     * redirect URI. The OAuth token will be embedded in the fragment (the part
+     * following the hash symbol) of that URI, which the JavaScript side of
+     * this extension will move to the query parameters.
+     *
+     * @param authorizationEndpoint
+     *     The full URL of the endpoint accepting OAuth authentication
+     *     requests.
+     *
+     * @param clientID
+     *     The ID of the OAuth client. This is normally determined ahead of
+     *     time by the OAuth service through some manual credential request
+     *     procedure.
+     *
+     * @param redirectURI
+     *     The URI that the OAuth service should redirect to upon successful
+     *     authentication.
+     */
+    public OAuthTokenField(String authorizationEndpoint, String clientID,
+            String redirectURI) {
+
+        // Init base field properties
+        super(PARAMETER_NAME, "GUAC_OAUTH_TOKEN");
+
+        // Build authorization URI from given values
+        try {
+            this.authorizationURI = authorizationEndpoint
+                    + "?scope=openid%20email%20profile"
+                    + "&response_type=id_token"
+                    + "&client_id=" + URLEncoder.encode(clientID, "UTF-8")
+                    + "&redirect_uri=" + URLEncoder.encode(redirectURI, "UTF-8")
+                    + "&nonce=" + UUID.randomUUID().toString();
+        }
+
+        // Java is required to provide UTF-8 support
+        catch (UnsupportedEncodingException e) {
+            throw new UnsupportedOperationException("Unexpected lack of UTF-8 support.", e);
+        }
+
+    }
+
+    /**
+     * Returns the full URI that this field should link to when a new token
+     * needs to be obtained from the OAuth service.
+     *
+     * @return
+     *     The full URI that this field should link to.
+     */
+    public String getAuthorizationURI() {
+        return authorizationURI;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java
deleted file mode 100644
index 5136830..0000000
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java
+++ /dev/null
@@ -1,153 +0,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.
- */
-
-package org.apache.guacamole.auth.oauth.token;
-
-import org.codehaus.jackson.annotate.JsonProperty;
-
-/**
- * The response produced from a successful request to the token endpoint of an
- * OAuth service.
- */
-public class TokenResponse {
-
-    /**
-     * An arbitrary access token which can be used for future requests against
-     * the API associated with the OAuth service.
-     */
-    private String accessToken;
-
-    /**
-     * The type of token present. This will always be "Bearer".
-     */
-    private String tokenType;
-
-    /**
-     * The number of seconds the access token will remain valid.
-     */
-    private int expiresIn;
-
-    /**
-     * A JWT (JSON Web Token) which containing identity information which has
-     * been cryptographically signed.
-     */
-    private String idToken;
-
-    /**
-     * Returns an arbitrary access token which can be used for future requests
-     * against the API associated with the OAuth service.
-     *
-     * @return
-     *     An arbitrary access token provided by the OAuth service.
-     */
-    @JsonProperty("access_token")
-    public String getAccessToken() {
-        return accessToken;
-    }
-
-    /**
-     * Sets the arbitrary access token which can be used for future requests
-     * against the API associated with the OAuth service.
-     *
-     * @param accessToken
-     *     The arbitrary access token provided by the OAuth service.
-     */
-    @JsonProperty("access_token")
-    public void setAccessToken(String accessToken) {
-        this.accessToken = accessToken;
-    }
-
-    /**
-     * Returns the type of token present in this response. This should always
-     * be "Bearer".
-     *
-     * @return
-     *     The type of token present in this response.
-     */
-    @JsonProperty("token_type")
-    public String getTokenType() {
-        return tokenType;
-    }
-
-    /**
-     * Sets the type of token present in this response. This should always be
-     * "Bearer".
-     *
-     * @param tokenType
-     *     The type of token present in this response, which should be
-     *     "Bearer".
-     */
-    @JsonProperty("token_type")
-    public void setTokenType(String tokenType) {
-        this.tokenType = tokenType;
-    }
-
-    /**
-     * Returns the number of seconds the access token within this response will
-     * remain valid.
-     *
-     * @return
-     *     The number of seconds the access token within this response will
-     *     remain valid.
-     */
-    @JsonProperty("expires_in")
-    public int getExpiresIn() {
-        return expiresIn;
-    }
-
-    /**
-     * Sets the number of seconds the access token within this response will
-     * remain valid.
-     *
-     * @param expiresIn
-     *     The number of seconds the access token within this response will
-     *     remain valid.
-     */
-    @JsonProperty("expires_in")
-    public void setExpiresIn(int expiresIn) {
-        this.expiresIn = expiresIn;
-    }
-
-    /**
-     * Returns a JWT (JSON Web Token) containing identity information which has
-     * been cryptographically signed by the OAuth service.
-     *
-     * @return
-     *     A JWT (JSON Web Token) containing identity information which has
-     *     been cryptographically signed by the OAuth service.
-     */
-    @JsonProperty("id_token")
-    public String getIdToken() {
-        return idToken;
-    }
-
-    /**
-     * Sets the JWT (JSON Web Token) containing identity information which has
-     * been cryptographically signed by the OAuth service.
-     *
-     * @param idToken
-     *     A JWT (JSON Web Token) containing identity information which has
-     *     been cryptographically signed by the OAuth service.
-     */
-    @JsonProperty("id_token")
-    public void setIdToken(String idToken) {
-        this.idToken = idToken;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java
deleted file mode 100644
index a328bde..0000000
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java
+++ /dev/null
@@ -1,101 +0,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.
- */
-
-package org.apache.guacamole.auth.oauth.token;
-
-import com.google.inject.Inject;
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.UniformInterfaceException;
-import com.sun.jersey.api.representation.Form;
-import javax.ws.rs.core.MediaType;
-import org.apache.guacamole.auth.oauth.AuthenticationProviderService;
-import org.apache.guacamole.auth.oauth.conf.ConfigurationService;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.glyptodon.guacamole.GuacamoleServerException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Provides relatively abstract means of producing authentication tokens from
- * the codes received from OAuth services.
- */
-public class TokenService {
-
-    /**
-     * Logger for this class.
-     */
-    private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class);
-
-    /**
-     * Service for retrieving OAuth configuration information.
-     */
-    @Inject
-    private ConfigurationService confService;
-
-    /**
-     * Jersey HTTP client.
-     */
-    @Inject
-    private Client client;
-
-    /**
-     * Given an authorization code previously received from the OAuth service
-     * via the "code" parameter provided to the redirect URL, retrieves and
-     * returns an authentication token.
-     *
-     * @param code
-     *     The value of the "code" parameter received from the OAuth service.
-     *
-     * @return
-     *     The authentication roken response received from the OAuth service.
-     *
-     * @throws GuacamoleException
-     *     If required properties within guacamole.properties cannot be read,
-     *     or if an error occurs while contacting the OAuth service.
-     */
-    public TokenResponse getTokenFromCode(String code)
-            throws GuacamoleException {
-
-        try {
-
-            // Generate POST data
-            Form form = new Form();
-            form.add("code", code);
-            form.add("client_id", confService.getClientID());
-            form.add("client_secret", confService.getClientSecret());
-            form.add("redirect_uri", confService.getRedirectURI());
-            form.add("grant_type", "authorization_code");
-
-            // POST code and client information to OAuth token endpoint
-            return client.resource(confService.getTokenEndpoint())
-                .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
-                .accept(MediaType.APPLICATION_JSON_TYPE)
-                .post(TokenResponse.class, form);
-
-        }
-
-        // Log any failure reaching the OAuth service
-        catch (UniformInterfaceException e) {
-            logger.debug("POST to token endpoint failed.", e);
-            throw new GuacamoleServerException("Unable to POST to token endpoint.", e);
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java
index 935c270..3a798eb 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/user/AuthenticatedUser.java
@@ -20,9 +20,9 @@
 package org.apache.guacamole.auth.oauth.user;
 
 import com.google.inject.Inject;
-import org.glyptodon.guacamole.net.auth.AbstractAuthenticatedUser;
-import org.glyptodon.guacamole.net.auth.AuthenticationProvider;
-import org.glyptodon.guacamole.net.auth.Credentials;
+import org.apache.guacamole.net.auth.AbstractAuthenticatedUser;
+import org.apache.guacamole.net.auth.AuthenticationProvider;
+import org.apache.guacamole.net.auth.Credentials;
 
 /**
  * An OAuth-specific implementation of AuthenticatedUser, associating a

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json
index e8f2fac..cc74547 100644
--- a/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json
+++ b/extensions/guacamole-auth-openid/src/main/resources/guac-manifest.json
@@ -1,6 +1,6 @@
 {
 
-    "guacamoleVersion" : "0.9.9",
+    "guacamoleVersion" : "0.9.9-incubating",
 
     "name"      : "OAuth Authentication Extension",
     "namespace" : "guac-oauth",
@@ -11,11 +11,8 @@
 
     "js" : [
         "oauthModule.js",
+        "oauthController.js",
         "oauthConfig.js"
-    ],
-
-    "resources" : {
-        "oauthCodeField.html" : "text/html"
-    }
+    ]
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html b/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html
deleted file mode 100644
index e6c4fff..0000000
--- a/extensions/guacamole-auth-openid/src/main/resources/oauthCodeField.html
+++ /dev/null
@@ -1 +0,0 @@
-<a href="{{field.authorizationURI}}">Log in using OAuth</a>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js b/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js
index ba6f0cc..4319656 100644
--- a/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js
+++ b/extensions/guacamole-auth-openid/src/main/resources/oauthConfig.js
@@ -23,9 +23,32 @@
 angular.module('guacOAuth').config(['formServiceProvider',
         function guacOAuthConfig(formServiceProvider) {
 
-    // Define field for code from OAuth service
-    formServiceProvider.registerFieldType("GUAC_OAUTH_CODE", {
-        templateUrl : 'app/ext/guac-oauth/oauthCodeField.html'
+    // Define field for token from OAuth service
+    formServiceProvider.registerFieldType("GUAC_OAUTH_TOKEN", {
+        template   : '',
+        controller : 'guacOAuthController',
+        module     : 'guacOAuth'
+    });
+
+}]);
+
+/**
+ * Config block which augments the existing routing, providing special handling
+ * for the "id_token=" fragments provided by OpenID Connect.
+ */
+angular.module('index').config(['$routeProvider',
+        function indexRouteConfig($routeProvider) {
+
+    // Transform "/#/id_token=..." to "/#/?id_token=..."
+    $routeProvider.when('/id_token=:response', {
+
+        template   : '',
+        controller : ['$location', function reroute($location) {
+            var params = $location.path().substring(1);
+            $location.url('/');
+            $location.search(params);
+        }]
+
     });
 
 }]);

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/fdc03133/extensions/guacamole-auth-openid/src/main/resources/oauthController.js
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/resources/oauthController.js b/extensions/guacamole-auth-openid/src/main/resources/oauthController.js
new file mode 100644
index 0000000..ba7a120
--- /dev/null
+++ b/extensions/guacamole-auth-openid/src/main/resources/oauthController.js
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * Controller for the "GUAC_OAUTH_TOKEN" field which simply redirects the user
+ * immediately to the authorization URI.
+ */
+angular.module('guacOAuth').controller('guacOAuthController', ['$scope',
+    function guacOAuthController($scope) {
+
+    // Redirect to authorization URI
+    window.location = $scope.field.authorizationURI;
+
+}]);