/* * 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;
/** * Simple implementation of <b>Realm</b> that reads an XML file to configure the valid users, passwords, and roles. The * file format (and default file location) are identical to those currently supported by Tomcat 3.X. * <p> * <strong>IMPLEMENTATION NOTE</strong>: It is assumed that the in-memory collection representing our defined users (and * their roles) is initialized at application startup and never modified again. Therefore, no thread synchronization is * performed around accesses to the principals collection. * * @author Craig R. McClanahan
*/ publicclass MemoryRealm extends RealmBase {
/** * The Digester we will use to process in-memory database files.
*/ privatestatic Digester digester = null; privatestaticfinal Object digesterLock = new Object();
/** * The pathname (absolute or relative to Catalina's current working directory) of the XML file containing our * database information.
*/ private String pathname = "conf/tomcat-users.xml";
/** * The set of valid Principals for this Realm, keyed by user name.
*/ privatefinal Map<String,GenericPrincipal> principals = new HashMap<>();
/** * The set of credentials for this Realm, keyed by user name.
*/ privatefinal Map<String,String> credentials = new HashMap<>();
/** * @return the pathname of our XML file containing user definitions.
*/ public String getPathname() {
return pathname;
}
/** * Set the pathname of our XML file containing user definitions. If a relative pathname is specified, it is resolved * against "catalina.base". * * @param pathname The new pathname
*/ publicvoid setPathname(String pathname) {
this.pathname = pathname;
}
// --------------------------------------------------------- Public Methods
@Override public Principal authenticate(String username, String credentials) {
// No user or no credentials // Can't possibly authenticate, don't bother the database then if (username == null || credentials == null) { if (log.isDebugEnabled()) {
log.debug(sm.getString("memoryRealm.authenticateFailure", username));
} returnnull;
}
GenericPrincipal principal = principals.get(username);
String password = null; if (principal != null) {
password = this.credentials.get(username);
}
if (principal == null || password == null) { // User was not found in the database or the password was null // Waste a bit of time as not to reveal that the user does not exist.
getCredentialHandler().mutate(credentials);
if (log.isDebugEnabled()) {
log.debug(sm.getString("memoryRealm.authenticateFailure", username));
} returnnull;
}
/** * Add a new user to the in-memory database. * * @param username User's username * @param password User's password (clear text) * @param roles Comma-delimited set of roles associated with this user
*/ void addUser(String username, String password, String roles) {
// Accumulate the list of roles for this user
List<String> list = new ArrayList<>();
roles += ","; while (true) { int comma = roles.indexOf(','); if (comma < 0) { break;
}
String role = roles.substring(0, comma).trim();
list.add(role);
roles = roles.substring(comma + 1);
}
// Construct and cache the Principal for this user
GenericPrincipal principal = new GenericPrincipal(username, list);
principals.put(username, principal);
credentials.put(username, password);
/** * @return a configured <code>Digester</code> to use for processing the XML input file, creating a new one if * necessary.
*/ protected Digester getDigester() { // Keep locking for subclass compatibility synchronized (digesterLock) { if (digester == null) {
digester = new Digester();
digester.setValidating(false); try {
digester.setFeature("http://apache.org/xml/features/allow-java-encodings", true);
} catch (Exception e) {
log.warn(sm.getString("memoryRealm.xmlFeatureEncoding"), e);
}
digester.addRuleSet(new MemoryRuleSet());
}
} return digester;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.