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

[25/29] incubator-guacamole-client git commit: GUACAMOLE-210: Add configuration options for scope, clock skew, etc., as well as sensible defaults.

GUACAMOLE-210: Add configuration options for scope, clock skew, etc., as well as sensible defaults.

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

Branch: refs/heads/master
Commit: 4dbf9a3f9ed899ca614f74871c05b4cd901b6e73
Parents: aaf1b79
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Aug 28 02:04:21 2017 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Mon Sep 25 13:06:45 2017 -0700

----------------------------------------------------------------------
 .../openid/AuthenticationProviderService.java   |   3 +-
 .../auth/openid/conf/ConfigurationService.java  | 157 ++++++++++++++++++-
 .../guacamole/auth/openid/form/TokenField.java  |  10 +-
 .../openid/token/TokenValidationService.java    |   6 +-
 4 files changed, 164 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/4dbf9a3f/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java
index 46e8b02..47d99ff 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/AuthenticationProviderService.java
@@ -118,9 +118,10 @@ public class AuthenticationProviderService {
                 // to the authorization page via JavaScript)
                 new TokenField(
                     confService.getAuthorizationEndpoint(),
+                    confService.getScope(),
                     confService.getClientID(),
                     confService.getRedirectURI(),
-                    nonceService.generate(30000 /* FIXME: Calculate appropriate value based on configuration */)
+                    nonceService.generate(confService.getMaxNonceValidity() * 60000L)
                 )
 
             }))

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/4dbf9a3f/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java
index 6f7e44b..c742d89 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/conf/ConfigurationService.java
@@ -22,6 +22,7 @@ package org.apache.guacamole.auth.openid.conf;
 import com.google.inject.Inject;
 import org.apache.guacamole.GuacamoleException;
 import org.apache.guacamole.environment.Environment;
+import org.apache.guacamole.properties.IntegerGuacamoleProperty;
 import org.apache.guacamole.properties.StringGuacamoleProperty;
 
 /**
@@ -31,6 +32,35 @@ import org.apache.guacamole.properties.StringGuacamoleProperty;
 public class ConfigurationService {
 
     /**
+     * The default claim type to use to retrieve an authenticated user's
+     * username.
+     */
+    private static final String DEFAULT_USERNAME_CLAIM_TYPE = "email";
+
+    /**
+     * The default space-separated list of OpenID scopes to request.
+     */
+    private static final String DEFAULT_SCOPE = "openid email profile";
+
+    /**
+     * The default amount of clock skew tolerated for timestamp comparisons
+     * between the Guacamole server and OpenID service clocks, in seconds.
+     */
+    private static final int DEFAULT_ALLOWED_CLOCK_SKEW = 30;
+
+    /**
+     * The default maximum amount of time that an OpenID token should remain
+     * valid, in minutes.
+     */
+    private static final int DEFAULT_MAX_TOKEN_VALIDITY = 300;
+
+    /**
+     * The default maximum amount of time that a nonce generated by the
+     * Guacamole server should remain valid, in minutes.
+     */
+    private static final int DEFAULT_MAX_NONCE_VALIDITY = 10;
+
+    /**
      * The authorization endpoint (URI) of the OpenID service.
      */
     private static final StringGuacamoleProperty OPENID_AUTHORIZATION_ENDPOINT =
@@ -77,6 +107,56 @@ public class ConfigurationService {
     };
 
     /**
+     * The space-separated list of OpenID scopes to request.
+     */
+    private static final StringGuacamoleProperty OPENID_SCOPE =
+            new StringGuacamoleProperty() {
+
+        @Override
+        public String getName() { return "openid-scope"; }
+
+    };
+
+    /**
+     * The amount of clock skew tolerated for timestamp comparisons between the
+     * Guacamole server and OpenID service clocks, in seconds.
+     */
+    private static final IntegerGuacamoleProperty OPENID_ALLOWED_CLOCK_SKEW =
+            new IntegerGuacamoleProperty() {
+
+        @Override
+        public String getName() { return "openid-allowed-clock-skew"; }
+
+    };
+
+    /**
+     * The maximum amount of time that an OpenID token should remain valid, in
+     * minutes.
+     */
+    private static final IntegerGuacamoleProperty OPENID_MAX_TOKEN_VALIDITY =
+            new IntegerGuacamoleProperty() {
+
+        @Override
+        public String getName() { return "openid-max-token-validity"; }
+
+    };
+
+    /**
+     * The maximum amount of time that a nonce generated by the Guacamole server
+     * should remain valid, in minutes. As each OpenID request has a unique
+     * nonce value, this imposes an upper limit on the amount of time any
+     * particular OpenID request can result in successful authentication within
+     * Guacamole.
+     */
+    private static final IntegerGuacamoleProperty OPENID_MAX_NONCE_VALIDITY =
+            new IntegerGuacamoleProperty() {
+
+        @Override
+        public String getName() { return "openid-max-nonce-validity"; }
+
+    };
+
+    /**
      * OpenID client ID which should be submitted to the OpenID service when
      * necessary. This value is typically provided by the OpenID service when
      * OpenID credentials are generated for your application.
@@ -196,18 +276,87 @@ public class ConfigurationService {
 
     /**
      * Returns the claim type which contains the authenticated user's username
-     * within any valid JWT, as configured with guacamole.properties.
+     * within any valid JWT, as configured with guacamole.properties. By
+     * default, this will be "email".
      *
      * @return
      *     The claim type which contains the authenticated user's username
      *     within any valid JWT, as configured with guacamole.properties.
      *
      * @throws GuacamoleException
-     *     If guacamole.properties cannot be parsed, or if the username claim
-     *     type property is missing.
+     *     If guacamole.properties cannot be parsed.
      */
     public String getUsernameClaimType() throws GuacamoleException {
-        return environment.getRequiredProperty(OPENID_USERNAME_CLAIM_TYPE);
+        return environment.getProperty(OPENID_USERNAME_CLAIM_TYPE, DEFAULT_USERNAME_CLAIM_TYPE);
+    }
+
+    /**
+     * Returns the space-separated list of OpenID scopes to request. By default,
+     * this will be "openid email profile". The OpenID scopes determine the
+     * information returned within the OpenID token, and thus affect what
+     * values can be used as an authenticated user's username.
+     *
+     * @return
+     *     The space-separated list of OpenID scopes to request when identifying
+     *     a user.
+     *
+     * @throws GuacamoleException
+     *     If guacamole.properties cannot be parsed.
+     */
+    public String getScope() throws GuacamoleException {
+        return environment.getProperty(OPENID_SCOPE, DEFAULT_SCOPE);
+    }
+
+    /**
+     * Returns the amount of clock skew tolerated for timestamp comparisons
+     * between the Guacamole server and OpenID service clocks, in seconds. Too
+     * much clock skew will affect token expiration calculations, possibly
+     * allowing old tokens to be used. By default, this will be 30.
+     *
+     * @return
+     *     The amount of clock skew tolerated for timestamp comparisons, in
+     *     seconds.
+     *
+     * @throws GuacamoleException
+     *     If guacamole.properties cannot be parsed.
+     */
+    public int getAllowedClockSkew() throws GuacamoleException {
+        return environment.getProperty(OPENID_ALLOWED_CLOCK_SKEW, DEFAULT_ALLOWED_CLOCK_SKEW);
+    }
+
+    /**
+     * Returns the maximum amount of time that an OpenID token should remain
+     * valid, in minutes. A token received from an OpenID service which is
+     * older than this amount of time will be rejected, even if it is otherwise
+     * valid. By default, this will be 300 (5 hours).
+     *
+     * @return
+     *     The maximum amount of time that an OpenID token should remain valid,
+     *     in minutes.
+     *
+     * @throws GuacamoleException
+     *     If guacamole.properties cannot be parsed.
+     */
+    public int getMaxTokenValidity() throws GuacamoleException {
+        return environment.getProperty(OPENID_MAX_TOKEN_VALIDITY, DEFAULT_MAX_TOKEN_VALIDITY);
+    }
+
+    /**
+     * Returns the maximum amount of time that a nonce generated by the
+     * Guacamole server should remain valid, in minutes. As each OpenID request
+     * has a unique nonce value, this imposes an upper limit on the amount of
+     * time any particular OpenID request can result in successful
+     * authentication within Guacamole. By default, this will be 10.
+     *
+     * @return
+     *     The maximum amount of time that a nonce generated by the Guacamole
+     *     server should remain valid, in minutes.
+     *
+     * @throws GuacamoleException
+     *     If guacamole.properties cannot be parsed.
+     */
+    public int getMaxNonceValidity() throws GuacamoleException {
+        return environment.getProperty(OPENID_MAX_NONCE_VALIDITY, DEFAULT_MAX_NONCE_VALIDITY);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/4dbf9a3f/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java
index 3f7c454..d99c367 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/form/TokenField.java
@@ -52,6 +52,10 @@ public class TokenField extends Field {
      *     The full URL of the endpoint accepting OpenID authentication
      *     requests.
      *
+     * @param scope
+     *     The space-delimited list of OpenID scopes to request from the
+     *     identity provider, such as "openid" or "openid email profile".
+     *
      * @param clientID
      *     The ID of the OpenID client. This is normally determined ahead of
      *     time by the OpenID service through some manual credential request
@@ -65,8 +69,8 @@ public class TokenField extends Field {
      *     A random string unique to this request. To defend against replay
      *     attacks, this value must cease being valid after its first use.
      */
-    public TokenField(String authorizationEndpoint, String clientID,
-            String redirectURI, String nonce) {
+    public TokenField(String authorizationEndpoint, String scope,
+            String clientID, String redirectURI, String nonce) {
 
         // Init base field properties
         super(PARAMETER_NAME, "GUAC_OPENID_TOKEN");
@@ -74,7 +78,7 @@ public class TokenField extends Field {
         // Build authorization URI from given values
         try {
             this.authorizationURI = authorizationEndpoint
-                    + "?scope=openid%20email%20profile"
+                    + "?scope=" + URLEncoder.encode(scope, "UTF-8")
                     + "&response_type=id_token"
                     + "&client_id=" + URLEncoder.encode(clientID, "UTF-8")
                     + "&redirect_uri=" + URLEncoder.encode(redirectURI, "UTF-8")

http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/4dbf9a3f/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java
----------------------------------------------------------------------
diff --git a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java
index 3d41eba..cde4f89 100644
--- a/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java
+++ b/extensions/guacamole-auth-openid/src/main/java/org/apache/guacamole/auth/openid/token/TokenValidationService.java
@@ -22,8 +22,6 @@ package org.apache.guacamole.auth.openid.token;
 import com.google.inject.Inject;
 import org.apache.guacamole.auth.openid.conf.ConfigurationService;
 import org.apache.guacamole.GuacamoleException;
-import org.apache.guacamole.GuacamoleSecurityException;
-import org.apache.guacamole.GuacamoleServerException;
 import org.jose4j.jwk.HttpsJwks;
 import org.jose4j.jwt.JwtClaims;
 import org.jose4j.jwt.MalformedClaimException;
@@ -82,8 +80,8 @@ public class TokenValidationService {
         // Create JWT consumer for validating received token
         JwtConsumer jwtConsumer = new JwtConsumerBuilder()
                 .setRequireExpirationTime()
-                .setMaxFutureValidityInMinutes(300)
-                .setAllowedClockSkewInSeconds(30)
+                .setMaxFutureValidityInMinutes(confService.getMaxTokenValidity())
+                .setAllowedClockSkewInSeconds(confService.getAllowedClockSkew())
                 .setRequireSubject()
                 .setExpectedIssuer(confService.getIssuer())
                 .setExpectedAudience(confService.getClientID())