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:06 UTC

[14/29] incubator-guacamole-client git commit: GUACAMOLE-210: POST code to OAuth service to retrieve token.

GUACAMOLE-210: POST code to OAuth service to retrieve token.


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/c3c6e0c4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/c3c6e0c4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/c3c6e0c4

Branch: refs/heads/master
Commit: c3c6e0c43b749929ae88d3c40d1da7bad2aa0309
Parents: c20271c
Author: Michael Jumper <mj...@apache.org>
Authored: Sat Jan 2 22:35:47 2016 -0800
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon Sep 25 13:06:43 2017 -0700

----------------------------------------------------------------------
 .../oauth/AuthenticationProviderService.java    |  15 ++
 .../OAuthAuthenticationProviderModule.java      |  25 +++
 .../guacamole/auth/oauth/TokenResponse.java     | 113 --------------
 .../auth/oauth/token/TokenResponse.java         | 153 +++++++++++++++++++
 .../auth/oauth/token/TokenService.java          | 101 ++++++++++++
 5 files changed, 294 insertions(+), 113 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c3c6e0c4/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 a1b9c46..5783faa 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
@@ -26,6 +26,8 @@ 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;
@@ -52,6 +54,12 @@ public class AuthenticationProviderService {
     private ConfigurationService confService;
 
     /**
+     * Service for producing authentication tokens from OAuth codes.
+     */
+    @Inject
+    private TokenService tokenService;
+
+    /**
      * Provider for AuthenticatedUser objects.
      */
     @Inject
@@ -84,9 +92,16 @@ public class AuthenticationProviderService {
 
         // TODO: Actually complete authentication using received code
         if (code != null) {
+
+            // POST code and client information to OAuth token endpoint
+            TokenResponse response = tokenService.getTokenFromCode(code);
+            logger.debug("RESPONSE: {}", response);
+
+            // Create corresponding authenticated user
             AuthenticatedUser authenticatedUser = authenticatedUserProvider.get();
             authenticatedUser.init("STUB", credentials);
             return authenticatedUser;
+
         }
 
         // Request auth code

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c3c6e0c4/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 e31c945..a5cef6d 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,7 +20,13 @@
 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;
@@ -43,6 +49,12 @@ 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.
      *
@@ -62,6 +74,15 @@ 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
@@ -73,6 +94,10 @@ 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/c3c6e0c4/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java
deleted file mode 100644
index 329fb16..0000000
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/TokenResponse.java
+++ /dev/null
@@ -1,113 +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;
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import java.util.Arrays;
-import javax.servlet.http.HttpServletRequest;
-import org.glyptodon.guacamole.GuacamoleException;
-import org.apache.guacamole.auth.oauth.conf.ConfigurationService;
-import org.apache.guacamole.auth.oauth.form.OAuthCodeField;
-import org.apache.guacamole.auth.oauth.user.AuthenticatedUser;
-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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Service providing convenience functions for the OAuth AuthenticationProvider
- * implementation.
- */
-public class AuthenticationProviderService {
-
-    /**
-     * Logger for this class.
-     */
-    private final Logger logger = LoggerFactory.getLogger(AuthenticationProviderService.class);
-
-    /**
-     * Service for retrieving OAuth configuration information.
-     */
-    @Inject
-    private ConfigurationService confService;
-
-    /**
-     * Provider for AuthenticatedUser objects.
-     */
-    @Inject
-    private Provider<AuthenticatedUser> authenticatedUserProvider;
-
-    /**
-     * Returns an AuthenticatedUser representing the user authenticated by the
-     * given credentials.
-     *
-     * @param credentials
-     *     The credentials to use for authentication.
-     *
-     * @return
-     *     An AuthenticatedUser representing the user authenticated by the
-     *     given credentials.
-     *
-     * @throws GuacamoleException
-     *     If an error occurs while authenticating the user, or if access is
-     *     denied.
-     */
-    public AuthenticatedUser authenticateUser(Credentials credentials)
-            throws GuacamoleException {
-
-        String code = null;
-
-        // Pull OAuth code 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) {
-            AuthenticatedUser authenticatedUser = authenticatedUserProvider.get();
-            authenticatedUser.init("STUB", credentials);
-            return authenticatedUser;
-        }
-
-        // Request auth code
-        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(
-                    confService.getAuthorizationEndpoint(),
-                    confService.getClientID(),
-                    confService.getRedirectURI()
-                )
-
-            }))
-        );
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/c3c6e0c4/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
new file mode 100644
index 0000000..5136830
--- /dev/null
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenResponse.java
@@ -0,0 +1,153 @@
+/*
+ * 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/c3c6e0c4/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
new file mode 100644
index 0000000..a328bde
--- /dev/null
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/oauth/token/TokenService.java
@@ -0,0 +1,101 @@
+/*
+ * 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);
+        }
+
+    }
+
+}