This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit d67968c4f5e221f9e32ced8aaff2bb6722ec09f7
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Sep 9 09:03:01 2022 +0100

    Add support for optionally validating the authentication realm
    
    Behaviour is unchanged unless the new realm property is set in the user
    properties.
    Document the authentication properties.
---
 .../org/apache/tomcat/websocket/Authenticator.java | 26 ++++++++++++++++++++++
 .../tomcat/websocket/BasicAuthenticator.java       |  4 ++++
 java/org/apache/tomcat/websocket/Constants.java    |  1 +
 .../tomcat/websocket/DigestAuthenticator.java      |  5 ++++-
 .../tomcat/websocket/LocalStrings.properties       |  1 +
 webapps/docs/web-socket-howto.xml                  | 19 +++++++++++++++-
 6 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/tomcat/websocket/Authenticator.java 
b/java/org/apache/tomcat/websocket/Authenticator.java
index 30787205cb..a49e18cb51 100644
--- a/java/org/apache/tomcat/websocket/Authenticator.java
+++ b/java/org/apache/tomcat/websocket/Authenticator.java
@@ -109,4 +109,30 @@ public abstract class Authenticator {
             throw new 
AuthenticationException(sm.getString("authenticator.nullPassword"));
         }
     }
+
+
+    protected void validateRealm(String userRealm, String serverRealm) throws 
AuthenticationException {
+        if (userRealm == null) {
+            return;
+        }
+
+        userRealm = userRealm.trim();
+        if (userRealm.length() == 0) {
+            return;
+        }
+
+        /*
+         * User has configured a realm. Only allow authentication to proceed if
+         * the realm in the authentication challenge matches (both BASIC and
+         * DIGEST are required to include a realm).
+         */
+        if (serverRealm != null) {
+            serverRealm = serverRealm.trim();
+            if (userRealm.equals(serverRealm)) {
+                return;
+            }
+        }
+
+        throw new 
AuthenticationException(sm.getString("authenticator.realmMismatch", userRealm, 
serverRealm));
+    }
 }
diff --git a/java/org/apache/tomcat/websocket/BasicAuthenticator.java 
b/java/org/apache/tomcat/websocket/BasicAuthenticator.java
index 63b0a3d0e5..e7731cbdb5 100644
--- a/java/org/apache/tomcat/websocket/BasicAuthenticator.java
+++ b/java/org/apache/tomcat/websocket/BasicAuthenticator.java
@@ -35,11 +35,15 @@ public class BasicAuthenticator extends Authenticator {
 
         String userName = (String) 
userProperties.get(Constants.WS_AUTHENTICATION_USER_NAME);
         String userPassword = (String) 
userProperties.get(Constants.WS_AUTHENTICATION_PASSWORD);
+        String userRealm = (String) 
userProperties.get(Constants.WS_AUTHENTICATION_REALM);
 
         validateUsername(userName);
         validatePassword(userPassword);
 
         Map<String, String> parameterMap = 
parseAuthenticateHeader(authenticateHeader);
+        String realm = parameterMap.get("realm");
+
+        validateRealm(userRealm, realm);
 
         String userPass = userName + ":" + userPassword;
         Charset charset;
diff --git a/java/org/apache/tomcat/websocket/Constants.java 
b/java/org/apache/tomcat/websocket/Constants.java
index e8b0ffaf1b..b506694fe0 100644
--- a/java/org/apache/tomcat/websocket/Constants.java
+++ b/java/org/apache/tomcat/websocket/Constants.java
@@ -139,6 +139,7 @@ public class Constants {
 
     public static final String WS_AUTHENTICATION_USER_NAME = 
"org.apache.tomcat.websocket.WS_AUTHENTICATION_USER_NAME";
     public static final String WS_AUTHENTICATION_PASSWORD = 
"org.apache.tomcat.websocket.WS_AUTHENTICATION_PASSWORD";
+    public static final String WS_AUTHENTICATION_REALM = 
"org.apache.tomcat.websocket.WS_AUTHENTICATION_REALM";
 
     public static final List<Extension> INSTALLED_EXTENSIONS;
 
diff --git a/java/org/apache/tomcat/websocket/DigestAuthenticator.java 
b/java/org/apache/tomcat/websocket/DigestAuthenticator.java
index 6552001c1c..cb6c9318de 100644
--- a/java/org/apache/tomcat/websocket/DigestAuthenticator.java
+++ b/java/org/apache/tomcat/websocket/DigestAuthenticator.java
@@ -41,13 +41,16 @@ public class DigestAuthenticator extends Authenticator {
 
         String userName = (String) 
userProperties.get(Constants.WS_AUTHENTICATION_USER_NAME);
         String userPassword = (String) 
userProperties.get(Constants.WS_AUTHENTICATION_PASSWORD);
+        String userRealm = (String) 
userProperties.get(Constants.WS_AUTHENTICATION_REALM);
 
         validateUsername(userName);
         validatePassword(userPassword);
 
         Map<String, String> parameterMap = 
parseAuthenticateHeader(authenticateHeader);
-
         String realm = parameterMap.get("realm");
+
+        validateRealm(userRealm, realm);
+
         String nonce = parameterMap.get("nonce");
         String messageQop = parameterMap.get("qop");
         String algorithm = parameterMap.get("algorithm") == null ? "MD5" : 
parameterMap.get("algorithm");
diff --git a/java/org/apache/tomcat/websocket/LocalStrings.properties 
b/java/org/apache/tomcat/websocket/LocalStrings.properties
index c86a75efab..030d43b7fb 100644
--- a/java/org/apache/tomcat/websocket/LocalStrings.properties
+++ b/java/org/apache/tomcat/websocket/LocalStrings.properties
@@ -31,6 +31,7 @@ asyncChannelWrapperSecure.wrongStateWrite=Flag that indicates 
a write is in prog
 
 authenticator.nullPassword=No password was provided to use for authentication
 authenticator.nullUserName=No user name was provided to use for authentication
+authenticator.realmMismatch=The user provided authentication realm [{0}] did 
not match the realm in the authentication challenge received from the server 
[{1}]
 
 backgroundProcessManager.processFailed=A background process failed
 
diff --git a/webapps/docs/web-socket-howto.xml 
b/webapps/docs/web-socket-howto.xml
index ac36b827de..8e7751d921 100644
--- a/webapps/docs/web-socket-howto.xml
+++ b/webapps/docs/web-socket-howto.xml
@@ -139,7 +139,24 @@
    <code>userProperties</code> of the provided
    <code>jakarta.websocket.ClientEndpointConfig</code>. The property is
    <ocde>org.apache.tomcat.websocket.MAX_REDIRECTIONS</ocde>. The default value
-   is 20. Redirection support can be disabled by configuring a value of 
zero.</p>
+   is 20. Redirection support can be disabled by configuring a value of zero.
+   </p>
+ 
+<p>When using the WebSocket client to connect to a server endpoint that 
requires
+   BASIC or DIGEST authentication, the following user properties must be set:
+   </p>
+   <ul>
+     <li><code>org.apache.tomcat.websocket.WS_AUTHENTICATION_USER_NAME</code>
+     </li>
+     <li><code>org.apache.tomcat.websocket.WS_AUTHENTICATION_PASSWORD</code>
+     </li>
+   </ul>
+   <p>Optionally, the WebSocket client can be configured only to send
+   credentials if the server authentication challenge includes a specific realm
+   by defining that realm in the optional user property:</p>
+   <ul>
+     <li><code>org.apache.tomcat.websocket.WS_AUTHENTICATION_REALM</code></li>
+   </ul>
 
 </section>
 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to