This is an automated email from the ASF dual-hosted git repository.
ChristopherSchultz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push:
new d4a85e0ba1 Remove JAASRealm support class
d4a85e0ba1 is described below
commit d4a85e0ba121b00ae1d21120f929ef0b7325a82f
Author: Christopher Schultz <[email protected]>
AuthorDate: Tue Oct 13 18:37:59 2026 +0100
Remove JAASRealm support class
---
.../catalina/realm/JAASMemoryLoginModule.java | 392 ---------------------
1 file changed, 392 deletions(-)
diff --git a/java/org/apache/catalina/realm/JAASMemoryLoginModule.java
b/java/org/apache/catalina/realm/JAASMemoryLoginModule.java
deleted file mode 100644
index 2a805cff3d..0000000000
--- a/java/org/apache/catalina/realm/JAASMemoryLoginModule.java
+++ /dev/null
@@ -1,392 +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.catalina.realm;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.Principal;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.TextInputCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.auth.login.FailedLoginException;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-
-import jakarta.servlet.http.HttpServletRequest;
-
-import org.apache.catalina.CredentialHandler;
-import org.apache.juli.logging.Log;
-import org.apache.juli.logging.LogFactory;
-import org.apache.tomcat.util.IntrospectionUtils;
-import org.apache.tomcat.util.digester.Digester;
-
-/**
- * <p>
- * Implementation of the JAAS <strong>LoginModule</strong> interface,
primarily for use in testing
- * <code>JAASRealm</code>. It utilizes an XML-format data file of
username/password/role information identical to that
- * supported by <code>org.apache.catalina.realm.MemoryRealm</code>.
- * </p>
- * <p>
- * This class recognizes the following string-valued options, which are
specified in the configuration file and passed
- * to {@link #initialize(Subject, CallbackHandler, Map, Map)} in the
<code>options</code> argument:
- * </p>
- * <ul>
- * <li><strong>pathname</strong> - Relative (to the pathname specified by the
"catalina.base" system property) or
- * absolute pathname to the XML file containing our user information, in the
format supported by {@link MemoryRealm}.
- * The default value matches the MemoryRealm default.</li>
- * <li><strong>credentialHandlerClassName</strong> - The fully qualified class
name of the CredentialHandler to use. If
- * not specified, {@link MessageDigestCredentialHandler} will be used.</li>
- * <li>Any additional options will be used to identify and call setters on the
{@link CredentialHandler}. For example,
- * <code>algorithm=SHA256</code> would result in a call to {@link
MessageDigestCredentialHandler#setAlgorithm(String)}
- * with a parameter of <code>"SHA256"</code></li>
- * </ul>
- * <p>
- * <strong>IMPLEMENTATION NOTE</strong> - This class extends {@link
MemoryRealm} rather than implementing
- * <code>Realm</code> directly, so that user lookup and credential validation
are performed against the XML file
- * configured for the memory realm.
- * </p>
- */
-public class JAASMemoryLoginModule extends MemoryRealm implements LoginModule {
- // We need to extend MemoryRealm to avoid class cast
-
- private static final Log log =
LogFactory.getLog(JAASMemoryLoginModule.class);
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * The callback handler responsible for answering our requests.
- */
- protected CallbackHandler callbackHandler = null;
-
-
- /**
- * Has our own <code>commit()</code> returned successfully?
- */
- protected boolean committed = false;
-
-
- /**
- * The configuration information for this <code>LoginModule</code>.
- */
- protected Map<String,?> options = null;
-
-
- /**
- * The absolute or relative pathname to the XML configuration file.
- */
- protected String pathname = "conf/tomcat-users.xml";
-
-
- /**
- * The <code>Principal</code> identified by our validation, or
<code>null</code> if validation failed.
- */
- protected Principal principal = null;
-
-
- /**
- * The <code>Principal</code> for the roles.
- */
- protected HashSet<Principal> roles = null;
-
-
- /**
- * The state information that is shared with other configured
<code>LoginModule</code> instances.
- */
- protected Map<String,?> sharedState = null;
-
-
- /**
- * The subject for which we are performing authentication.
- */
- protected Subject subject = null;
-
-
- // --------------------------------------------------------- Public Methods
-
- /**
- * Constructs a new JAASMemoryLoginModule.
- */
- public JAASMemoryLoginModule() {
- if (log.isTraceEnabled()) {
- log.trace("MEMORY LOGIN MODULE");
- }
- }
-
-
- @Override
- public boolean abort() throws LoginException {
-
- // If our authentication was not successful, just return false
- if (principal == null) {
- return false;
- }
-
- // Clean up if overall authentication failed
- if (committed) {
- logout();
- } else {
- principal = null;
- }
- if (log.isTraceEnabled()) {
- log.trace("Abort");
- }
- return true;
- }
-
-
- @Override
- public boolean commit() throws LoginException {
- if (log.isTraceEnabled()) {
- log.trace("commit " + principal);
- }
-
- // If authentication was not successful, just return false
- if (principal == null) {
- return false;
- }
-
- // Add our Principal to the Subject if needed
- if (!subject.getPrincipals().contains(principal)) {
- subject.getPrincipals().add(principal);
- // Add the roles as additional subjects as per the contract with
the
- // JAASRealm
- if (principal instanceof GenericPrincipal) {
- this.roles = new HashSet<>();
- String[] roles = ((GenericPrincipal) principal).getRoles();
- for (String role : roles) {
- GenericPrincipal roleGp = new GenericPrincipal(role);
- subject.getPrincipals().add(roleGp);
- this.roles.add(roleGp);
- }
- }
- }
-
- committed = true;
- return true;
- }
-
-
- @Override
- public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String,?> sharedState,
- Map<String,?> options) {
- if (log.isTraceEnabled()) {
- log.trace("Init");
- }
-
- // Save configuration values
- this.subject = subject;
- this.callbackHandler = callbackHandler;
- this.sharedState = sharedState;
- this.options = options;
-
- // Perform instance-specific initialization
- Object option = options.get("pathname");
- if (option instanceof String) {
- this.pathname = (String) option;
- }
-
- CredentialHandler credentialHandler = null;
- option = options.get("credentialHandlerClassName");
- if (option instanceof String) {
- try {
- Class<?> clazz = Class.forName((String) option);
- credentialHandler = (CredentialHandler)
clazz.getConstructor().newInstance();
- } catch (ReflectiveOperationException | ClassCastException e) {
- throw new IllegalArgumentException(e);
- }
- }
- if (credentialHandler == null) {
- credentialHandler = new MessageDigestCredentialHandler();
- }
-
- for (Entry<String,?> entry : options.entrySet()) {
- if ("pathname".equals(entry.getKey())) {
- continue;
- }
- if ("credentialHandlerClassName".equals(entry.getKey())) {
- continue;
- }
- // Skip any non-String values since any value we are interested in
- // will be a String.
- if (entry.getValue() instanceof String) {
- IntrospectionUtils.setProperty(credentialHandler,
entry.getKey(), (String) entry.getValue());
- }
- }
- setCredentialHandler(credentialHandler);
-
- // Load our defined Principals
- load();
- }
-
-
- @Override
- public boolean login() throws LoginException {
- // Set up our CallbackHandler requests
- if (callbackHandler == null) {
- throw new
LoginException(sm.getString("jaasMemoryLoginModule.noCallbackHandler"));
- }
- Callback[] callbacks = new Callback[10];
- callbacks[0] = new NameCallback("Username: ");
- callbacks[1] = new PasswordCallback("Password: ", false);
- callbacks[2] = new TextInputCallback("nonce");
- callbacks[3] = new TextInputCallback("nc");
- callbacks[4] = new TextInputCallback("cnonce");
- callbacks[5] = new TextInputCallback("qop");
- callbacks[6] = new TextInputCallback("realmName");
- callbacks[7] = new TextInputCallback("digestA2");
- callbacks[8] = new TextInputCallback("algorithm");
- callbacks[9] = new TextInputCallback("authMethod");
-
- // Interact with the user to retrieve the username and password
- String username;
- String password;
- String nonce;
- String nc;
- String cnonce;
- String qop;
- String realmName;
- String digestA2;
- String algorithm;
- String authMethod;
-
- try {
- callbackHandler.handle(callbacks);
- username = ((NameCallback) callbacks[0]).getName();
- char[] passwordArray = ((PasswordCallback)
callbacks[1]).getPassword();
- password = (passwordArray == null) ? null : new
String(passwordArray);
- nonce = ((TextInputCallback) callbacks[2]).getText();
- nc = ((TextInputCallback) callbacks[3]).getText();
- cnonce = ((TextInputCallback) callbacks[4]).getText();
- qop = ((TextInputCallback) callbacks[5]).getText();
- realmName = ((TextInputCallback) callbacks[6]).getText();
- digestA2 = ((TextInputCallback) callbacks[7]).getText();
- algorithm = ((TextInputCallback) callbacks[8]).getText();
- authMethod = ((TextInputCallback) callbacks[9]).getText();
- } catch (IOException | UnsupportedCallbackException e) {
- throw new
LoginException(sm.getString("jaasMemoryLoginModule.callbackHandlerError",
e.toString()));
- }
-
- // Validate the username and password we have received
- if (authMethod == null) {
- // BASIC or FORM
- principal = super.authenticate(username, password);
- } else if (authMethod.equals(HttpServletRequest.DIGEST_AUTH)) {
- principal = super.authenticate(username, password, nonce, nc,
cnonce, qop, realmName, digestA2, algorithm);
- } else if (authMethod.equals(HttpServletRequest.CLIENT_CERT_AUTH)) {
- principal = super.getPrincipal(username);
- } else {
- throw new
LoginException(sm.getString("jaasMemoryLoginModule.unknownAuthenticationMethod"));
- }
-
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("jaasMemoryLoginModule.login", username,
principal));
- }
-
- // Report results based on success or failure
- if (principal != null) {
- return true;
- } else {
- throw new
FailedLoginException(sm.getString("jaasMemoryLoginModule.invalidCredentials"));
- }
- }
-
-
- @Override
- public boolean logout() throws LoginException {
- subject.getPrincipals().remove(principal);
- if (principal instanceof GenericPrincipal) {
- for (Principal role : roles) {
- subject.getPrincipals().remove(role);
- }
- }
- committed = false;
- principal = null;
- roles = null;
- return true;
- }
-
-
- // ---------------------------------------------------------- Realm Methods
- // ------------------------------------------------------ Protected Methods
-
- /**
- * Load the contents of our configuration file.
- */
- protected void load() {
- // Validate the existence of our configuration file
- File file = new File(pathname);
- if (!file.isAbsolute()) {
- String catalinaBase = getCatalinaBase();
- if (catalinaBase == null) {
- log.error(sm.getString("jaasMemoryLoginModule.noCatalinaBase",
pathname));
- return;
- } else {
- file = new File(catalinaBase, pathname);
- }
- }
- if (!file.canRead()) {
- log.error(sm.getString("jaasMemoryLoginModule.noConfig",
file.getAbsolutePath()));
- return;
- }
-
- // Load the contents of our configuration file
- Digester digester = new Digester();
- digester.setValidating(false);
- digester.addRuleSet(new MemoryRuleSet());
- try {
- digester.push(this);
- digester.parse(file);
- } catch (Exception e) {
- log.error(sm.getString("jaasMemoryLoginModule.parseError",
file.getAbsolutePath()), e);
- } finally {
- digester.reset();
- }
- }
-
- private String getCatalinaBase() {
- // Have to get this via a callback as that is the only link we have
back
- // to the defining Realm. Can't use the system property as that may not
- // be set/correct in an embedded scenario
-
- if (callbackHandler == null) {
- return null;
- }
-
- Callback[] callbacks = new Callback[1];
- callbacks[0] = new TextInputCallback("catalinaBase");
-
- String result;
-
- try {
- callbackHandler.handle(callbacks);
- result = ((TextInputCallback) callbacks[0]).getText();
- } catch (IOException | UnsupportedCallbackException e) {
- return null;
- }
-
- return result;
- }
-}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]