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