You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2008/09/23 18:49:25 UTC
svn commit: r698236 - in /tomcat/trunk: java/org/apache/catalina/realm/
webapps/docs/ webapps/docs/config/
Author: markt
Date: Tue Sep 23 09:49:25 2008
New Revision: 698236
URL: http://svn.apache.org/viewvc?rev=698236&view=rev
Log:
Add new LockOut Realm plus docs
Added:
tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java (with props)
Modified:
tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/realm/mbeans-descriptors.xml
tomcat/trunk/webapps/docs/config/realm.xml
tomcat/trunk/webapps/docs/realm-howto.xml
Modified: tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties?rev=698236&r1=698235&r2=698236&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/realm/LocalStrings.properties Tue Sep 23 09:49:25 2008
@@ -92,4 +92,6 @@
combinedRealm.authStart=Attempting to authenticate user "{0}" with realm "{1}"
combinedRealm.authFailed=Failed to authenticate user "{0}" with realm "{1}"
combinedRealm.authSucess=Authenticated user "{0}" with realm "{1}"
-combinedRealm.addRealm=Add "{0}" realm, making a total of "{1}" realms
\ No newline at end of file
+combinedRealm.addRealm=Add "{0}" realm, making a total of "{1}" realms
+lockOutRealm.authLockedUser=An attempt was made to authenticate the locked user "{0}"
+lockOutRealm.removeWarning=User "{0}" was removed from the failed users cache after {1} seconds to keep the cache size within the limit set
\ No newline at end of file
Added: tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java?rev=698236&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java (added)
+++ tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java Tue Sep 23 09:49:25 2008
@@ -0,0 +1,415 @@
+/*
+ * 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.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+/**
+ * This class extends the CombinedRealm (hence it can wrap other Realms) to
+ * provide a user lock out mechanism if there are too many failed
+ * authentication attempts in a given period of time. To ensure correct
+ * operation, there is a reasonable degree of synchronisation in this Realm.
+ * This Realm does not require modification to the underlying Realms or the
+ * associated user storage mecahisms. It achieves this by recording all failed
+ * logins, including those for users that do not exist. To prevent a DOS by
+ * deliberating making requests with invalid users (and hence causing this cache
+ * to grow) the size of the list of users that have failed authentication is
+ * limited.
+ */
+public class LockOutRealm extends CombinedRealm {
+
+ private static Log log = LogFactory.getLog(LockOutRealm.class);
+
+ /**
+ * The number of times in a row a user has to fail authentication to be
+ * locked out. Defaults to 5.
+ */
+ protected int failureCount = 5;
+
+ /**
+ * The time (in seconds) a user is locked out for after too many
+ * authentication failures. Defaults to 300 (5 minutes).
+ */
+ protected int lockOutTime = 300;
+
+ /**
+ * Number of users that have failed authentication to keep in cache. Over
+ * time the cache will grow to this size and may not shrink. Defaults to
+ * 1000.
+ */
+ protected int cacheSize = 1000;
+
+ /**
+ * If a failed user is removed from the cache because the cache is too big
+ * before it has been in the cache for at least this period of time (in
+ * seconds) a warning message will be logged. Defaults to 3600 (1 hour).
+ */
+ protected int cacheRemovalWarningTime = 3600;
+
+ /**
+ * Users whose last authentication attempt failed. Entries will be ordered
+ * in access order from least recent to most recent.
+ */
+ protected Map<String,LockRecord> failedUsers = null;
+
+
+ /**
+ * Prepare for the beginning of active use of the public methods of this
+ * component. This method should be called before any of the public
+ * methods of this component are utilized. It should also send a
+ * LifecycleEvent of type START_EVENT to any registered listeners.
+ *
+ * @exception LifecycleException if this component detects a fatal error
+ * that prevents this component from being used
+ */
+ public void start() throws LifecycleException {
+ // Configure the list of failed users to delete the oldest entry once it
+ // exceeds the specified size
+ failedUsers = new LinkedHashMap<String, LockRecord>(cacheSize, 0.75f,
+ true) {
+ protected boolean removeEldestEntry(
+ Map.Entry<String, LockRecord> eldest) {
+ if (size() > cacheSize) {
+ // Check to see if this element has been removed too quickly
+ long timeInCache = (System.currentTimeMillis() -
+ eldest.getValue().getLastFailureTime())/1000;
+
+ if (timeInCache < cacheRemovalWarningTime) {
+ log.warn(sm.getString("lockOutRealm.removeWarning",
+ eldest.getKey(), Long.valueOf(timeInCache)));
+ }
+ return true;
+ }
+ return false;
+ }
+ };
+
+ super.start();
+ }
+
+
+ /**
+ * Return the Principal associated with the specified username and
+ * credentials, if there is one; otherwise return <code>null</code>.
+ *
+ * @param username Username of the Principal to look up
+ * @param credentials Password or other credentials to use in
+ * authenticating this username
+ */
+ public Principal authenticate(String username, byte[] credentials) {
+ if (isLocked(username)) {
+ // Trying to authenticate a locked user is an automatic failure
+ registerAuthFailure(username);
+
+ log.warn(sm.getString("lockOutRealm.authLockedUser", username));
+ return null;
+ }
+
+ Principal authenticatedUser = super.authenticate(username, credentials);
+
+ if (authenticatedUser == null) {
+ registerAuthFailure(username);
+ } else {
+ registerAuthSuccess(username);
+ }
+ return authenticatedUser;
+ }
+
+
+ /**
+ * Return the Principal associated with the specified username, which
+ * matches the digest calculated using the given parameters using the
+ * method described in RFC 2069; otherwise return <code>null</code>.
+ *
+ * @param username Username of the Principal to look up
+ * @param clientDigest Digest which has been submitted by the client
+ * @param nOnce Unique (or supposedly unique) token which has been used
+ * for this request
+ * @param realm Realm name
+ * @param md5a2 Second MD5 digest used to calculate the digest :
+ * MD5(Method + ":" + uri)
+ */
+ public Principal authenticate(String username, String clientDigest,
+ String once, String nc, String cnonce, String qop,
+ String realmName, String md5a2) {
+
+ if (isLocked(username)) {
+ // Trying to authenticate a locked user is an automatic failure
+ registerAuthFailure(username);
+
+ log.warn(sm.getString("lockOutRealm.authLockedUser", username));
+ return null;
+ }
+
+ Principal authenticatedUser = super.authenticate(username, clientDigest,
+ once, nc, cnonce, qop, realmName, md5a2);
+
+ if (authenticatedUser == null) {
+ registerAuthFailure(username);
+ } else {
+ registerAuthSuccess(username);
+ }
+ return authenticatedUser;
+ }
+
+
+ /**
+ * Return the Principal associated with the specified username and
+ * credentials, if there is one; otherwise return <code>null</code>.
+ *
+ * @param username Username of the Principal to look up
+ * @param credentials Password or other credentials to use in
+ * authenticating this username
+ */
+ public Principal authenticate(String username, String credentials) {
+ if (isLocked(username)) {
+ // Trying to authenticate a locked user is an automatic failure
+ registerAuthFailure(username);
+
+ log.warn(sm.getString("lockOutRealm.authLockedUser", username));
+ return null;
+ }
+
+ Principal authenticatedUser = super.authenticate(username, credentials);
+
+ if (authenticatedUser == null) {
+ registerAuthFailure(username);
+ } else {
+ registerAuthSuccess(username);
+ }
+ return authenticatedUser;
+ }
+
+
+ /**
+ * Return the Principal associated with the specified chain of X509
+ * client certificates. If there is none, return <code>null</code>.
+ *
+ * @param certs Array of client certificates, with the first one in
+ * the array being the certificate of the client itself.
+ */
+ public Principal authenticate(X509Certificate[] certs) {
+ String username = null;
+ if (certs != null && certs.length >0) {
+ username = certs[0].getSubjectDN().getName();
+ }
+
+ if (isLocked(username)) {
+ // Trying to authenticate a locked user is an automatic failure
+ registerAuthFailure(username);
+
+ log.warn(sm.getString("lockOutRealm.authLockedUser", username));
+ return null;
+ }
+
+ Principal authenticatedUser = super.authenticate(certs);
+
+ if (authenticatedUser == null) {
+ registerAuthFailure(username);
+ } else {
+ registerAuthSuccess(username);
+ }
+ return authenticatedUser;
+ }
+
+
+ /**
+ * Unlock the specified username. This will remove all records of
+ * authentication failures for this user.
+ *
+ * @param username The user to unlock
+ */
+ public void unlock(String username) {
+ // Auth success clears the lock record so...
+ registerAuthSuccess(username);
+ }
+
+ /*
+ * Checks to see if the current user is locked. If this is associated with
+ * a login attempt, then the last access time will be recorded and any
+ * attempt to authenticated a locked user will log a warning.
+ */
+ private boolean isLocked(String username) {
+ LockRecord lockRecord = null;
+ synchronized (this) {
+ lockRecord = failedUsers.get(username);
+ }
+
+ // No lock record means user can't be locked
+ if (lockRecord == null) {
+ return false;
+ }
+
+ // Check to see if user is locked
+ if (lockRecord.getFailures() >= failureCount &&
+ (System.currentTimeMillis() -
+ lockRecord.getLastFailureTime())/1000 < lockOutTime) {
+ return true;
+ }
+
+ // User has not, yet, exceeded lock thresholds
+ return false;
+ }
+
+
+ /*
+ * After successful authentication, any record of previous authentication
+ * failure is removed.
+ */
+ private synchronized void registerAuthSuccess(String username) {
+ // Successful authentication means removal from the list of failed users
+ failedUsers.remove(username);
+ }
+
+
+ /*
+ * After a failed authentication, add the record of the failed
+ * authentication.
+ */
+ private void registerAuthFailure(String username) {
+ LockRecord lockRecord = null;
+ synchronized (this) {
+ if (!failedUsers.containsKey(username)) {
+ lockRecord = new LockRecord();
+ failedUsers.put(username, lockRecord);
+ } else {
+ lockRecord = failedUsers.get(username);
+ if (lockRecord.getFailures() >= failureCount &&
+ ((System.currentTimeMillis() -
+ lockRecord.getLastFailureTime())/1000)
+ > lockOutTime) {
+ // User was previously locked out but lockout has now
+ // expired so reset failure count
+ lockRecord.setFailures(0);
+ }
+ }
+ }
+ lockRecord.registerFailure();
+ }
+
+
+ /**
+ * Get the number of failed authentication attempts required to lock the
+ * user account.
+ * @return the failureCount
+ */
+ public int getFailureCount() {
+ return failureCount;
+ }
+
+
+ /**
+ * Set the number of failed authentication attempts required to lock the
+ * user account.
+ * @param failureCount the failureCount to set
+ */
+ public void setFailureCount(int failureCount) {
+ this.failureCount = failureCount;
+ }
+
+
+ /**
+ * Get the period for which an account will be locked.
+ * @return the lockOutTime
+ */
+ public int getLockOutTime() {
+ return lockOutTime;
+ }
+
+
+ /**
+ * Set the period for which an account will be locked.
+ * @param lockOutTime the lockOutTime to set
+ */
+ public void setLockOutTime(int lockOutTime) {
+ this.lockOutTime = lockOutTime;
+ }
+
+
+ /**
+ * Get the maximum number of users for which authentication failure will be
+ * kept in the cache.
+ * @return the cacheSize
+ */
+ public int getCacheSize() {
+ return cacheSize;
+ }
+
+
+ /**
+ * Set the maximum number of users for which authentication failure will be
+ * kept in the cache.
+ * @param cacheSize the cacheSize to set
+ */
+ public void setCacheSize(int cacheSize) {
+ this.cacheSize = cacheSize;
+ }
+
+
+ /**
+ * Get the minimum period a failed authentication must remain in the cache
+ * to avoid generating a warning if it is removed from the cache to make
+ * space for a new entry.
+ * @return the cacheRemovalWarningTime
+ */
+ public int getCacheRemovalWarningTime() {
+ return cacheRemovalWarningTime;
+ }
+
+
+ /**
+ * Set the minimum period a failed authentication must remain in the cache
+ * to avoid generating a warning if it is removed from the cache to make
+ * space for a new entry.
+ * @param cacheRemovalWarningTime the cacheRemovalWarningTime to set
+ */
+ public void setCacheRemovalWarningTime(int cacheRemovalWarningTime) {
+ this.cacheRemovalWarningTime = cacheRemovalWarningTime;
+ }
+
+
+ protected class LockRecord {
+ private AtomicInteger failures = new AtomicInteger(0);
+ private long lastFailureTime = 0;
+
+ public int getFailures() {
+ return failures.get();
+ }
+
+ public void setFailures(int theFailures) {
+ failures.set(theFailures);
+ }
+
+ public long getLastFailureTime() {
+ return lastFailureTime;
+ }
+
+ public void registerFailure() {
+ failures.incrementAndGet();
+ lastFailureTime = System.currentTimeMillis();
+ }
+ }
+}
Propchange: tomcat/trunk/java/org/apache/catalina/realm/LockOutRealm.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/java/org/apache/catalina/realm/mbeans-descriptors.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/mbeans-descriptors.xml?rev=698236&r1=698235&r2=698236&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/mbeans-descriptors.xml (original)
+++ tomcat/trunk/java/org/apache/catalina/realm/mbeans-descriptors.xml Tue Sep 23 09:49:25 2008
@@ -34,8 +34,7 @@
type="java.lang.String"/>
<attribute name="digest"
- description="Digest algorithm used in storing passwords in a
- non-plaintext format"
+ description="Digest algorithm used in storing passwords in a non-plaintext format"
type="java.lang.String"/>
<attribute name="localDataSource"
@@ -47,18 +46,15 @@
type="java.lang.String"/>
<attribute name="userCredCol"
- description="The column in the user table that holds the user's
- credentials"
+ description="The column in the user table that holds the user's credentials"
type="java.lang.String"/>
<attribute name="userNameCol"
- description="The column in the user table that holds the user's
- username"
+ description="The column in the user table that holds the user's username"
type="java.lang.String"/>
<attribute name="userRoleTable"
- description="The table that holds the relation between user's and
- roles"
+ description="The table that holds the relation between user's and roles"
type="java.lang.String"/>
<attribute name="userTable"
@@ -74,16 +70,13 @@
</mbean>
<mbean name="JAASRealm"
- description="Implmentation of Realm that authenticates users via the
- Java Authentication and Authorization Service (JAAS)"
+ description="Implmentation of Realm that authenticates users via the Java Authentication and Authorization Service (JAAS)"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.JAASRealm">
<attribute name="appName"
- description="The application name passed to the JAAS LoginContext,
- which uses it to select the set of relevant
- LoginModules"
+ description="The application name passed to the JAAS LoginContext, which uses it to select the set of relevant LoginModules"
type="java.lang.String"/>
<attribute name="className"
@@ -92,23 +85,19 @@
writeable="false"/>
<attribute name="digest"
- description="Digest algorithm used in storing passwords in a
- non-plaintext format"
+ description="Digest algorithm used in storing passwords in a non-plaintext format"
type="java.lang.String"/>
<attribute name="roleClassNames"
- description="Comma-delimited list of javax.security.Principal classes
- that represent security roles"
+ description="Comma-delimited list of javax.security.Principal classes that represent security roles"
type="java.lang.String"/>
<attribute name="userClassNames"
- description="Comma-delimited list of javax.security.Principal classes
- that represent individual users"
+ description="Comma-delimited list of javax.security.Principal classes that represent individual users"
type="java.lang.String"/>
<attribute name="validate"
- description="Should we validate client certificate chains when they
- are presented?"
+ description="Should we validate client certificate chains when they are presented?"
type="java.lang.String"/>
@@ -120,8 +109,7 @@
<mbean name="JDBCRealm"
- description="Implementation of Realm that works with any JDBC
- supported database"
+ description="Implementation of Realm that works with any JDBC supported database"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.JDBCRealm">
@@ -132,23 +120,19 @@
writeable="false"/>
<attribute name="connectionName"
- description="The connection username to use when trying to connect to
- the database"
+ description="The connection username to use when trying to connect to the database"
type="java.lang.String"/>
<attribute name="connectionPassword"
- description="The connection URL to use when trying to connect to the
- database"
+ description="The connection URL to use when trying to connect to the database"
type="java.lang.String"/>
<attribute name="connectionURL"
- description="The connection URL to use when trying to connect to the
- database"
+ description="The connection URL to use when trying to connect to the database"
type="java.lang.String"/>
<attribute name="digest"
- description="Digest algorithm used in storing passwords in a
- non-plaintext format"
+ description="Digest algorithm used in storing passwords in a non-plaintext format"
type="java.lang.String"/>
<attribute name="driverName"
@@ -160,18 +144,15 @@
type="java.lang.String"/>
<attribute name="userCredCol"
- description="The column in the user table that holds the user's
- credentials"
+ description="The column in the user table that holds the user's credentials"
type="java.lang.String"/>
<attribute name="userNameCol"
- description="The column in the user table that holds the user's
- username"
+ description="The column in the user table that holds the user's username"
type="java.lang.String"/>
<attribute name="userRoleTable"
- description="The table that holds the relation between user's and
- roles"
+ description="The table that holds the relation between user's and roles"
type="java.lang.String"/>
<attribute name="userTable"
@@ -186,9 +167,7 @@
</mbean>
<mbean name="JNDIRealm"
- description="Implementation of Realm that works with a directory
- server accessed via the Java Naming and Directory
- Interface (JNDI) APIs"
+ description="Implementation of Realm that works with a directory server accessed via the Java Naming and Directory Interface (JNDI) APIs"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.JNDIRealm">
@@ -215,8 +194,7 @@
type="java.lang.String"/>
<attribute name="digest"
- description="Digest algorithm used in storing passwords in a
- non-plaintext format"
+ description="Digest algorithm used in storing passwords in a non-plaintext format"
type="java.lang.String"/>
<attribute name="roleBase"
@@ -232,8 +210,7 @@
type="java.lang.String"/>
<attribute name="roleSubtree"
- description="Should we search the entire subtree for matching
- memberships?"
+ description="Should we search the entire subtree for matching memberships?"
type="boolean"/>
<attribute name="userBase"
@@ -249,8 +226,7 @@
type="java.lang.String"/>
<attribute name="userRoleName"
- description="The name of the attribute in the user's entry containing
- roles for that user"
+ description="The name of the attribute in the user's entry containing roles for that user"
type="java.lang.String"/>
<attribute name="userSearch"
@@ -258,8 +234,7 @@
type="java.lang.String"/>
<attribute name="userSubtree"
- description="Should we search the entire subtree for matching
- users?"
+ description="Should we search the entire subtree for matching users?"
type="boolean"/>
@@ -270,8 +245,7 @@
</mbean>
<mbean name="MemoryRealm"
- description="Simple implementation of Realm that reads an XML file to
- configure the valid users, passwords, and roles"
+ description="Simple implementation of Realm that reads an XML file to configure the valid users, passwords, and roles"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.MemoryRealm">
@@ -282,8 +256,7 @@
writeable="false"/>
<attribute name="pathname"
- description="The pathname of the XML file containing our database
- information"
+ description="The pathname of the XML file containing our database information"
type="java.lang.String"/>
<operation name="start" description="Start" impact="ACTION" returnType="void" />
@@ -294,8 +267,7 @@
</mbean>
<mbean name="UserDatabaseRealm"
- description="Realm connected to a UserDatabase as a global JNDI
- resource"
+ description="Realm connected to a UserDatabase as a global JNDI resource"
domain="Catalina"
group="Realm"
type="org.apache.catalina.realm.UserDatabaseRealm">
@@ -311,4 +283,103 @@
</mbean>
+ <mbean name="CombinedRealm"
+ description="Realm implementation that can be used to chain multiple realms"
+ domain="Catalina"
+ group="Realm"
+ type="org.apache.catalina.realm.CombinedRealm">
+
+ <attribute name="className"
+ description="Fully qualified class name of the managed object"
+ type="java.lang.String"
+ writeable="false"/>
+
+ <attribute name="realms"
+ description="The set of realms that the combined realm is wrapping"
+ type="[Ljavax.management.ObjectName;"
+ writeable="false"/>
+
+ <operation name="addRealm"
+ description="Add a new Realm to the set of Realms wrapped by this realm"
+ impact="ACTION"
+ returnType="void">
+ <parameter name="theRealm"
+ description="New Realm to add"
+ type="org.apache.catalina.Realm"/>
+ </operation>
+
+ <operation name="start"
+ description="Start"
+ impact="ACTION"
+ returnType="void" />
+
+ <operation name="stop"
+ description="Stop"
+ impact="ACTION"
+ returnType="void" />
+
+ </mbean>
+
+ <mbean name="LockOutRealm"
+ description="Realm implementation that can be used to wrap existing realms to provide a user lock-out capability"
+ domain="Catalina"
+ group="Realm"
+ type="org.apache.catalina.realm.LockOutRealm">
+
+ <attribute name="className"
+ description="Fully qualified class name of the managed object"
+ type="java.lang.String"
+ writeable="false"/>
+
+ <attribute name="realms"
+ description="The set of realms that the lockout realm is wrapping"
+ type="[Ljavax.management.ObjectName;"
+ writeable="false"/>
+
+ <attribute name="cacheRemovalWarningTime"
+ description="If a failed user is removed from the cache because the cache is too big before it has been in the cache for at least this period of time (in seconds) a warning message will be logged. Defaults to 3600 (1 hour)."
+ type="int" />
+
+ <attribute name="cacheSize"
+ description="Number of users that have failed authentication to keep in cache. Over time the cache will grow to this size and may not shrink. Defaults to 1000."
+ type="int" />
+
+ <attribute name="failureCount"
+ description="The number of times in a row a user has to fail authentication to be locked out. Defaults to 5."
+ type="int" />
+
+ <attribute name="lockOutTime"
+ description="The time (in seconds) a user is locked out for after too many authentication failures. Defaults to 300 (5 minutes)."
+ type="int" />
+
+ <operation name="addRealm"
+ description="Add a new Realm to the set of Realms wrapped by this realm"
+ impact="ACTION"
+ returnType="void">
+ <parameter name="theRealm"
+ description="New Realm to add"
+ type="org.apache.catalina.Realm"/>
+ </operation>
+
+ <operation name="unlock"
+ description="Unlock the specified user"
+ impact="ACTION"
+ returnType="void">
+ <parameter name="username"
+ description="User to unlock"
+ type="java.lang.String"/>
+ </operation>
+
+ <operation name="start"
+ description="Start"
+ impact="ACTION"
+ returnType="void" />
+
+ <operation name="stop"
+ description="Stop"
+ impact="ACTION"
+ returnType="void" />
+
+ </mbean>
+
</mbeans-descriptors>
Modified: tomcat/trunk/webapps/docs/config/realm.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/realm.xml?rev=698236&r1=698235&r2=698236&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/realm.xml (original)
+++ tomcat/trunk/webapps/docs/config/realm.xml Tue Sep 23 09:49:25 2008
@@ -608,12 +608,68 @@
listed. Authentication against any Realm will be sufficient to authenticate
the user.</p>
- <p>The Combined Realm implementation does not support any additional
+ <p>The CombinedRealm implementation does not support any additional
attributes.</p>
<p>See the <a href="../realm-howto.html">Container-Managed Security
Guide</a> for more information on setting up container managed security
- using the Combined Realm component.</p>
+ using the CombinedRealm component.</p>
+
+ <h3>LockOut Realm (org.apache.catalina.realm.LockOutRealm)</h3>
+
+ <p><strong>LockOutRealm</strong> is an implementation of the Tomcat 6
+ <code>Realm</code> interface that extends the CombinedRealm to provide lock
+ out functionality to provide a user lock out mechanism if there are too many
+ failed authentication attempts in a given period of time.</p>
+
+ <p>To ensure correct operation, there is a reasonable degree of
+ synchronisation in this Realm.</p>
+
+ <p>This Realm does not require modification to the underlying Realms or the
+ associated user storage mecahisms. It achieves this by recording all failed
+ logins, including those for users that do not exist. To prevent a DOS by
+ deliberating making requests with invalid users (and hence causing this
+ cache to grow) the size of the list of users that have failed authentication
+ is limited.</p>
+
+ <p>Sub-realms are defined by nesting <code>Realm</code> elements inside the
+ <code>Realm</code> element that defines the LockOutRealm. Authentication
+ will be attempted against each <code>Realm</code> in the order they are
+ listed. Authentication against any Realm will be sufficient to authenticate
+ the user.</p>
+
+ <p>The LockOutRealm implementation supports the following additional
+ attributes.</p>
+
+ <attributes>
+
+ <attribute name="cacheRemovalWarningTime" required="false">
+ <p>If a failed user is removed from the cache because the cache is too
+ big before it has been in the cache for at least this period of time (in
+ seconds) a warning message will be logged. Defaults to 3600 (1 hour).</p>
+ </attribute>
+
+ <attribute name="cacheSize" required="false">
+ <p>Number of users that have failed authentication to keep in cache. Over
+ time the cache will grow to this size and may not shrink. Defaults to
+ 1000.</p>
+ </attribute>
+
+ <attribute name="failureCount" required="false">
+ <p>The number of times in a row a user has to fail authentication to be
+ locked out. Defaults to 5.</p>
+ </attribute>
+
+ <attribute name="lockOutTime" required="false">
+ <p>The time (in seconds) a user is locked out for after too many
+ authentication failures. Defaults to 300 (5 minutes).</p>
+ </attribute>
+
+ </attributes>
+
+ <p>See the <a href="../realm-howto.html">Container-Managed Security
+ Guide</a> for more information on setting up container managed security
+ using the LockOutRealm component.</p>
</subsection>
@@ -623,9 +679,10 @@
<section name="Nested Components">
- <h3>Combined Realm Implementation</h3>
+ <h3>CombinedRealm Implementation</h3>
- <p>If you are using the <em>Combined Realm Implementation</em>
+ <p>If you are using the <em>CombinedRealm Implementation</em> or a Realm
+ that extends the CombinedRealm, e.g. the LockOutRealm,
<strong><Realm></strong> elements may be nested inside it.</p>
<h3>Other Realm Implementations</h3>
Modified: tomcat/trunk/webapps/docs/realm-howto.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/realm-howto.xml?rev=698236&r1=698235&r2=698236&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/realm-howto.xml (original)
+++ tomcat/trunk/webapps/docs/realm-howto.xml Tue Sep 23 09:49:25 2008
@@ -55,6 +55,8 @@
<a href="#JNDIRealm">JNDIRealm</a><br />
<a href="#MemoryRealm">MemoryRealm</a><br />
<a href="#JAASRealm">JAASRealm</a><br />
+<a href="#CombinedRealm">CombinedRealm</a><br />
+<a href="#LockOutRealm">LockOutRealm</a><br />
</blockquote>
</p>
@@ -1485,7 +1487,7 @@
the user.</p>
<h3>Realm Element Attributes</h3>
- <p>To configure CombinedRealm, you create a <code><Realm></code>
+ <p>To configure a CombinedRealm, you create a <code><Realm></code>
element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code>
file within your <code><Engine></code> or <code><Host></code>.
You can also nest inside a <code><Context></code> node in a
@@ -1520,6 +1522,85 @@
</subsection>
+<subsection name="LockOutRealm">
+
+ <h3>Introduction</h3>
+
+ <p><strong>LockOutRealm</strong> is an implementation of the Tomcat 6
+ <code>Realm</code> interface that extends the CombinedRealm to provide lock
+ out functionality to provide a user lock out mechanism if there are too many
+ failed authentication attempts in a given period of time.</p>
+
+ <p>To ensure correct operation, there is a reasonable degree of
+ synchronisation in this Realm.</p>
+
+ <p>This Realm does not require modification to the underlying Realms or the
+ associated user storage mecahisms. It achieves this by recording all failed
+ logins, including those for users that do not exist. To prevent a DOS by
+ deliberating making requests with invalid users (and hence causing this
+ cache to grow) the size of the list of users that have failed authentication
+ is limited.</p>
+
+ <p>Sub-realms are defined by nesting <code>Realm</code> elements inside the
+ <code>Realm</code> element that defines the LockOutRealm. Authentication
+ will be attempted against each <code>Realm</code> in the order they are
+ listed. Authentication against any Realm will be sufficient to authenticate
+ the user.</p>
+
+ <h3>Realm Element Attributes</h3>
+ <p>To configure a LockOutRealm, you create a <code><Realm></code>
+ element and nest it in your <code>$CATALINA_BASE/conf/server.xml</code>
+ file within your <code><Engine></code> or <code><Host></code>.
+ You can also nest inside a <code><Context></code> node in a
+ <code>context.xml</code> file. The following attributes are supported by
+ this implementation:</p>
+
+<attributes>
+
+ <attribute name="className" required="true">
+ <p>The fully qualified Java class name of this Realm implementation.
+ You <strong>MUST</strong> specify the value
+ "<code>org.apache.catalina.realm.LockOutRealm</code>" here.</p>
+ </attribute>
+
+ <attribute name="cacheRemovalWarningTime" required="false">
+ <p>If a failed user is removed from the cache because the cache is too
+ big before it has been in the cache for at least this period of time (in
+ seconds) a warning message will be logged. Defaults to 3600 (1 hour).</p>
+ </attribute>
+
+ <attribute name="cacheSize" required="false">
+ <p>Number of users that have failed authentication to keep in cache. Over
+ time the cache will grow to this size and may not shrink. Defaults to
+ 1000.</p>
+ </attribute>
+
+ <attribute name="failureCount" required="false">
+ <p>The number of times in a row a user has to fail authentication to be
+ locked out. Defaults to 5.</p>
+ </attribute>
+
+ <attribute name="lockOutTime" required="false">
+ <p>The time (in seconds) a user is locked out for after too many
+ authentication failures. Defaults to 300 (5 minutes).</p>
+ </attribute>
+
+</attributes>
+
+<h3>Example</h3>
+
+<p>Here is an example of how your server.xml snippet should look to add lock out
+functionality to a UserDatabase Realm.</p>
+
+<source>
+<Realm className="org.apache.catalina.realm.LockOutRealm" >
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase"/>
+<Realm/>
+</source>
+
+</subsection>
+
</section>
</body>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org