markt 2004/11/27 10:29:44
Modified: catalina/src/share/org/apache/catalina/realm
DataSourceRealm.java JAASRealm.java JDBCRealm.java
LocalStrings.properties MemoryRealm.java
RealmBase.java UserDatabaseRealm.java
webapps/tomcat-docs realm-howto.xml
Log:
Fix bug 19767. Port support for digested passwords with DIGEST
authentication for JDBC and DataSource realms from TC5.
Remove unused imports in o.a.c.realm package
Revision Changes Path
1.4 +135 -73
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/DataSourceRealm.java
Index: DataSourceRealm.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/DataSourceRealm.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DataSourceRealm.java 26 Aug 2004 21:37:21 -0000 1.3
+++ DataSourceRealm.java 27 Nov 2004 18:29:44 -0000 1.4
@@ -18,36 +18,20 @@
package org.apache.catalina.realm;
-import java.io.File;
-import java.security.MessageDigest;
import java.security.Principal;
import java.sql.Connection;
-import java.sql.Driver;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
-import java.util.Properties;
-import javax.naming.InitialContext;
import javax.naming.Context;
-import javax.naming.NamingException;
import javax.sql.DataSource;
-import org.apache.catalina.Container;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.Logger;
-import org.apache.catalina.Realm;
-import org.apache.catalina.Server;
import org.apache.catalina.ServerFactory;
import org.apache.catalina.core.StandardServer;
-import org.apache.catalina.util.HexUtils;
-import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
-import org.apache.catalina.util.Base64;
/**
*
@@ -323,64 +307,37 @@
*/
private Principal authenticate(Connection dbConnection,
String username,
- String credentials)
- throws SQLException {
+ String credentials) {
- ResultSet rs = null;
- PreparedStatement stmt = null;
- ArrayList list = null;
- try {
- // Look up the user's credentials
- String dbCredentials = null;
- stmt = credentials(dbConnection, username);
- rs = stmt.executeQuery();
- while (rs.next()) {
- dbCredentials = rs.getString(1).trim();
- }
- rs.close();
- rs = null;
- stmt.close();
- stmt = null;
- if (dbCredentials == null) {
- return (null);
- }
-
- // Validate the user's credentials
- boolean validated = false;
- if (hasMessageDigest()) {
- // Hex hashes should be compared case-insensitive
- validated =
(digest(credentials).equalsIgnoreCase(dbCredentials));
- } else
- validated = (digest(credentials).equals(dbCredentials));
-
- if (validated) {
- if (debug >= 2)
- log(sm.getString("dataSourceRealm.authenticateSuccess",
- username));
- } else {
- if (debug >= 2)
- log(sm.getString("dataSourceRealm.authenticateFailure",
- username));
- return (null);
- }
-
- // Accumulate the user's roles
- list = new ArrayList();
- stmt = roles(dbConnection, username);
- rs = stmt.executeQuery();
- while (rs.next()) {
- list.add(rs.getString(1).trim());
- }
- } finally {
- if (rs != null) {
- rs.close();
- }
- if (stmt != null) {
- stmt.close();
- }
+ // No user - can't possibly authenticate
+ if (username == null) {
+ return (null);
}
+ String dbCredentials = getPassword(username);
+
+ // Validate the user's credentials
+ boolean validated = false;
+ if (hasMessageDigest()) {
+ // Hex hashes should be compared case-insensitive
+ validated =
(digest(credentials).equalsIgnoreCase(dbCredentials));
+ } else
+ validated = (digest(credentials).equals(dbCredentials));
+
+ if (validated) {
+ if (debug >=2)
+ log(sm.getString("dataSourceRealm.authenticateSuccess",
+ username));
+ } else {
+ if (debug >=2)
+ log(sm.getString("dataSourceRealm.authenticateFailure",
+ username));
+ return (null);
+ }
+
+ ArrayList list = getRoles(username);
+
// Create and return a suitable Principal for this user
return (new GenericPrincipal(this, username, credentials, list));
@@ -455,7 +412,7 @@
*/
protected String getName() {
- return (this.name);
+ return (DataSourceRealm.name);
}
@@ -465,6 +422,60 @@
*/
protected String getPassword(String username) {
+ ResultSet rs = null;
+ PreparedStatement stmt = null;
+ ArrayList list = null;
+ Connection dbConnection = null;
+
+ // Ensure that we have an open database connection
+ dbConnection = open();
+ if (dbConnection == null) {
+ return null;
+ }
+
+ try {
+ // Look up the user's credentials
+ String dbCredentials = null;
+ stmt = credentials(dbConnection, username);
+ rs = stmt.executeQuery();
+ if (rs.next()) {
+ dbCredentials = rs.getString(1);
+ }
+ rs.close();
+ rs = null;
+ stmt.close();
+ stmt = null;
+ if (dbCredentials == null) {
+ return (null);
+ }
+ dbCredentials = dbCredentials.trim();
+
+ return (dbCredentials);
+
+ } catch(SQLException e) {
+ log(sm.getString("datasourceRealm.getPassword.exception",
+ username));
+ } finally {
+ try {
+ if (rs != null) {
+ rs.close();
+ }
+ if (stmt != null) {
+ stmt.close();
+ }
+ if( !dbConnection.getAutoCommit() ) {
+ dbConnection.commit();
+ }
+ } catch (SQLException e) {
+ log(sm.getString("datasourceRealm.getPassword.exception",
+ username));
+
+ }
+ // Release the database connection we just used
+ close(dbConnection);
+ dbConnection = null;
+
+ }
return (null);
}
@@ -475,10 +486,61 @@
*/
protected Principal getPrincipal(String username) {
- return (null);
+ return (new GenericPrincipal(this,
+ username,
+ getPassword(username),
+ getRoles(username)));
}
+
+
+ /**
+ * Return the roles associated with the gven user name.
+ */
+ protected ArrayList getRoles(String username) {
+
+ ResultSet rs = null;
+ PreparedStatement stmt = null;
+ Connection dbConnection = null;
+
+ // Ensure that we have an open database connection
+ dbConnection = open();
+ if (dbConnection == null) {
+ return null;
+ }
+
+ try {
+ // Accumulate the user's roles
+ ArrayList list = new ArrayList();
+ stmt = roles(dbConnection, username);
+ rs = stmt.executeQuery();
+ while (rs.next()) {
+ String role = rs.getString(1);
+ if (role != null) {
+ list.add(role.trim());
+ }
+ }
+
+ return (list);
+ } catch(SQLException e) {
+ log(sm.getString("datasourceRealm.getRoles.exception",
username));
+ } finally {
+ try {
+ if (rs != null) {
+ rs.close();
+ }
+ if (stmt != null) {
+ stmt.close();
+ }
+ } catch(SQLException e) {
+ log(sm.getString("datasourceRealm.getRoles.exception",
+ username));
+ }
+ }
+
+ return (null);
+ }
/**
1.6 +2 -4
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/JAASRealm.java
Index: JAASRealm.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/JAASRealm.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- JAASRealm.java 26 Aug 2004 21:37:21 -0000 1.5
+++ JAASRealm.java 27 Nov 2004 18:29:44 -0000 1.6
@@ -21,14 +21,12 @@
import java.security.Principal;
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.login.AccountExpiredException;
import javax.security.auth.login.CredentialExpiredException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
-import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.util.StringManager;
@@ -296,7 +294,7 @@
*/
protected String getName() {
- return (this.name);
+ return (JAASRealm.name);
}
1.25 +117 -68
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/JDBCRealm.java
Index: JDBCRealm.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/JDBCRealm.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- JDBCRealm.java 26 Aug 2004 21:37:21 -0000 1.24
+++ JDBCRealm.java 27 Nov 2004 18:29:44 -0000 1.25
@@ -44,7 +44,8 @@
* @author Craig R. McClanahan
* @author Carson McDonald
* @author Ignacio Ortega
-* @version $Revision$ $Date$*/
+* @version $Revision$ $Date$
+*/
public class JDBCRealm
extends RealmBase {
@@ -384,81 +385,42 @@
* @param username Username of the Principal to look up
* @param credentials Password or other credentials to use in
* authenticating this username
- *
- * @exception SQLException if a database error occurs
*/
public synchronized Principal authenticate(Connection dbConnection,
String username,
- String credentials)
- throws SQLException {
-
- // Look up the user's credentials
- String dbCredentials = null;
- PreparedStatement stmt = null;
- ResultSet rs = null;
-
- try {
- stmt = credentials(dbConnection, username);
- rs = stmt.executeQuery();
-
- if (rs.next()) {
- dbCredentials = rs.getString(1);
- }
- rs.close();
- rs = null;
- if (dbCredentials == null) {
- return (null);
- }
-
- dbCredentials = dbCredentials.trim();
+ String credentials) {
- // Validate the user's credentials
- boolean validated = false;
- if (hasMessageDigest()) {
- // Hex hashes should be compared case-insensitive
- validated =
(digest(credentials).equalsIgnoreCase(dbCredentials));
- } else {
- validated = (digest(credentials).equals(dbCredentials));
- }
+ // No user - can't possibly authenticate
+ if (username == null) {
+ return (null);
+ }
- if (validated) {
- if (debug >= 2)
- log(sm.getString("jdbcRealm.authenticateSuccess",
- username));
- } else {
- if (debug >= 2)
- log(sm.getString("jdbcRealm.authenticateFailure",
- username));
- return (null);
- }
+ // Look up the user's credentials
+ String dbCredentials = getPassword(username);
- // Accumulate the user's roles
- ArrayList roleList = new ArrayList();
- stmt = roles(dbConnection, username);
- rs = stmt.executeQuery();
- while (rs.next()) {
- String role = rs.getString(1);
- if (null!=role) {
- roleList.add(role.trim());
- }
- }
- rs.close();
- rs = null;
+ // Validate the user's credentials
+ boolean validated = false;
+ if (hasMessageDigest()) {
+ // Hex hashes should be compared case-insensitive
+ validated =
(digest(credentials).equalsIgnoreCase(dbCredentials));
+ } else {
+ validated = (digest(credentials).equals(dbCredentials));
+ }
- // Create and return a suitable Principal for this user
- return (new GenericPrincipal(this, username, credentials,
roleList));
- } finally {
- if (rs!=null) {
- try {
- rs.close();
- } catch(SQLException e) {
- log(sm.getString("jdbcRealm.abnormalCloseResultSet"));
- }
- }
- dbConnection.commit();
+ if (validated) {
+ if (debug >= 2)
+ log(sm.getString("jdbcRealm.authenticateSuccess", username));
+ } else {
+ if (debug >=2)
+ log(sm.getString("jdbcRealm.authenticateFailure",
username));
+ return (null);
}
+ ArrayList roles = getRoles(username);
+
+ // Create and return a suitable Principal for this user
+ return (new GenericPrincipal(this, username, credentials, roles));
}
@@ -542,7 +504,7 @@
*/
protected String getName() {
- return (this.name);
+ return (JDBCRealm.name);
}
@@ -552,6 +514,44 @@
*/
protected String getPassword(String username) {
+ // Look up the user's credentials
+ String dbCredentials = null;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+
+ try {
+ stmt = credentials(dbConnection, username);
+ rs = stmt.executeQuery();
+
+ if (rs.next()) {
+ dbCredentials = rs.getString(1);
+ }
+ rs.close();
+ rs = null;
+ if (dbCredentials == null) {
+ return (null);
+ }
+
+ dbCredentials = dbCredentials.trim();
+ return dbCredentials;
+
+ } catch(SQLException e){
+ log(sm.getString("jdbcRealm.getPassword.exception", username));
+ } finally {
+ if (rs!=null) {
+ try {
+ rs.close();
+ } catch(SQLException e) {
+ log(sm.getString("jdbcRealm.abnormalCloseResultSet"));
+ }
+ }
+ try {
+ dbConnection.commit();
+ } catch (SQLException e) {
+ log(sm.getString("jdbcRealm.getPassword.exception",
username));
+ }
+ }
+
return (null);
}
@@ -562,11 +562,60 @@
*/
protected Principal getPrincipal(String username) {
- return (null);
+ return (new GenericPrincipal(this,
+ username,
+ getPassword(username),
+ getRoles(username)));
}
+ /**
+ * Return the roles associated with the gven user name.
+ */
+ protected ArrayList getRoles(String username) {
+
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+
+ try {
+ // Accumulate the user's roles
+ ArrayList roleList = new ArrayList();
+ stmt = roles(dbConnection, username);
+ rs = stmt.executeQuery();
+ while (rs.next()) {
+ String role = rs.getString(1);
+ if (null!=role) {
+ roleList.add(role.trim());
+ }
+ }
+ rs.close();
+ rs = null;
+
+ return (roleList);
+
+ } catch(SQLException e){
+ log(sm.getString("jdbcRealm.getRoles.exception", username));
+ } finally {
+ if (rs!=null) {
+ try {
+ rs.close();
+ } catch(SQLException e) {
+ log(sm.getString("jdbcRealm.abnormalCloseResultSet"));
+ }
+ }
+ try {
+ dbConnection.commit();
+ } catch (SQLException e) {
+ log(sm.getString("jdbcRealm.getRoles.exception", username));
+ }
+ }
+
+ return (null);
+
+ }
+
+
/**
* Open (if necessary) and return a database connection for use by
* this Realm.
1.10 +5 -1
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/LocalStrings.properties
Index: LocalStrings.properties
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/LocalStrings.properties,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- LocalStrings.properties 12 Dec 2003 22:39:22 -0000 1.9
+++ LocalStrings.properties 27 Nov 2004 18:29:44 -0000 1.10
@@ -13,6 +13,8 @@
jdbcRealm.authenticateSuccess=Username {0} successfully authenticated
jdbcRealm.close=Exception closing database connection
jdbcRealm.exception=Exception performing authentication
+jdbcRealm.getPassword.exception=Exception retrieving password for "{0}"
+jdbcRealm.getRoles.exception=Exception retrieving roles for "{0}"
jdbcRealm.open=Exception opening database connection
jndiRealm.authenticateFailure=Username {0} NOT successfully authenticated
jndiRealm.authenticateSuccess=Username {0} successfully authenticated
@@ -41,4 +43,6 @@
dataSourceRealm.authenticateSuccess=Username {0} successfully authenticated
dataSourceRealm.close=Exception closing database connection
dataSourceRealm.exception=Exception performing authentication
+datasourceRealm.getPassword.exception=Exception retrieving password for "{0}"
+datasourceRealm.getRoles.exception=Exception retrieving roles for "{0}"
dataSourceRealm.open=Exception opening database connection
1.15 +2 -8
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/MemoryRealm.java
Index: MemoryRealm.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/MemoryRealm.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- MemoryRealm.java 26 Aug 2004 21:37:21 -0000 1.14
+++ MemoryRealm.java 27 Nov 2004 18:29:44 -0000 1.15
@@ -23,13 +23,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.catalina.Container;
-import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleException;
-import org.apache.catalina.LifecycleListener;
-import org.apache.catalina.Logger;
-import org.apache.catalina.Realm;
-import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
import org.apache.commons.digester.Digester;
@@ -243,7 +237,7 @@
*/
protected String getName() {
- return (this.name);
+ return (MemoryRealm.name);
}
1.15 +99 -15
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/RealmBase.java
Index: RealmBase.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/RealmBase.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- RealmBase.java 26 Aug 2004 21:37:21 -0000 1.14
+++ RealmBase.java 27 Nov 2004 18:29:44 -0000 1.15
@@ -24,10 +24,10 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
-import java.io.File;
+import java.io.UnsupportedEncodingException;
+
import org.apache.catalina.Container;
import org.apache.catalina.Lifecycle;
-import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.Logger;
@@ -74,6 +74,11 @@
*/
protected String digest = null;
+ /**
+ * The encoding charset for the digest.
+ */
+ protected String digestEncoding = null;
+
/**
* Descriptive information about this Realm implementation.
@@ -202,6 +207,24 @@
/**
+ * Returns the digest encoding charset.
+ *
+ * @return The charset (may be null) for platform default
+ */
+ public String getDigestEncoding() {
+ return digestEncoding;
+ }
+
+ /**
+ * Sets the digest encoding charset.
+ *
+ * @param charset The charset (null for platform default)
+ */
+ public void setDigestEncoding(String charset) {
+ digestEncoding = charset;
+ }
+
+ /**
* Return descriptive information about this Realm implementation and
* the corresponding version number, in the format
* <code><description>/<version></code>.
@@ -262,9 +285,18 @@
String serverCredentials = getPassword(username);
- if ( (serverCredentials == null)
- || (!serverCredentials.equals(credentials)) )
+ boolean validated;
+ if ( serverCredentials == null ) {
+ validated = false;
+ } else if(hasMessageDigest()) {
+ validated =
serverCredentials.equalsIgnoreCase(digest(credentials));
+ } else {
+ validated = serverCredentials.equals(credentials);
+ }
+
+ if(! validated ) {
return null;
+ }
return getPrincipal(username);
@@ -322,14 +354,24 @@
String md5a1 = getDigest(username, realm);
if (md5a1 == null)
return null;
- String serverDigestValue;
- if (!"auth".equals(qop))
- serverDigestValue = md5a1 + ":" + nOnce + ":" + md5a2;
- else
- serverDigestValue = md5a1 + ":" + nOnce + ":" + nc + ":"
+ String serverDigestValue = md5a1 + ":" + nOnce + ":" + nc + ":"
+ cnonce + ":" + qop + ":" + md5a2;
+
+ byte[] valueBytes = null;
+ if(getDigestEncoding() == null) {
+ valueBytes = serverDigestValue.getBytes();
+ } else {
+ try {
+ valueBytes = serverDigestValue.getBytes(getDigestEncoding());
+ } catch (UnsupportedEncodingException uee) {
+ log("Illegal digestEncoding: " + getDigestEncoding(), uee);
+ throw new IllegalArgumentException(uee.getMessage());
+ }
+ }
+
String serverDigest =
-
md5Encoder.encode(md5Helper.digest(serverDigestValue.getBytes()));
+ md5Encoder.encode(md5Helper.digest(valueBytes));
+
//System.out.println("Server digest : " + serverDigest);
if (serverDigest.equals(clientDigest))
@@ -389,12 +431,18 @@
*/
public boolean hasRole(Principal principal, String role) {
+ // Should be overriten in JAASRealm - to avoid pretty inefficient
conversions
if ((principal == null) || (role == null) ||
!(principal instanceof GenericPrincipal))
return (false);
+
GenericPrincipal gp = (GenericPrincipal) principal;
- if (!(gp.getRealm() == this))
- return (false);
+ if (!(gp.getRealm() == this)) {
+ if (debug >= 2) {
+ log("Different realm " + this + " " + gp.getRealm());
+ }
+ }
+
boolean result = gp.hasRole(role);
if (debug >= 2) {
String name = principal.getName();
@@ -539,7 +587,20 @@
synchronized (this) {
try {
md.reset();
- md.update(credentials.getBytes());
+
+ byte[] bytes = null;
+ if(getDigestEncoding() == null) {
+ bytes = credentials.getBytes();
+ } else {
+ try {
+ bytes = credentials.getBytes(getDigestEncoding());
+ } catch (UnsupportedEncodingException uee) {
+ log("Illegal digestEncoding: " +
getDigestEncoding(), uee);
+ throw new IllegalArgumentException(uee.getMessage());
+ }
+ }
+ md.update(bytes);
+
return (HexUtils.convert(md.digest()));
} catch (Exception e) {
log(sm.getString("realmBase.digest"), e);
@@ -565,10 +626,30 @@
throw new IllegalStateException();
}
}
+
+ if (hasMessageDigest()) {
+ // Use pre-generated digest
+ return getPassword(username);
+ }
+
String digestValue = username + ":" + realmName + ":"
+ getPassword(username);
+
+ byte[] valueBytes = null;
+ if(getDigestEncoding() == null) {
+ valueBytes = digestValue.getBytes();
+ } else {
+ try {
+ valueBytes = digestValue.getBytes(getDigestEncoding());
+ } catch (UnsupportedEncodingException uee) {
+ log("Illegal digestEncoding: " + getDigestEncoding(), uee);
+ throw new IllegalArgumentException(uee.getMessage());
+ }
+ }
+
byte[] digest =
- md5Helper.digest(digestValue.getBytes());
+ md5Helper.digest(valueBytes);
+
return md5Encoder.encode(digest);
}
@@ -657,8 +738,11 @@
// Obtain a new message digest with "digest" encryption
MessageDigest md =
(MessageDigest) MessageDigest.getInstance(algorithm).clone();
+
// encode the credentials
+ // Should use the digestEncoding, but that's not a static field
md.update(credentials.getBytes());
+
// Digest the credentials and return as hexadecimal
return (HexUtils.convert(md.digest()));
} catch(Exception ex) {
1.11 +31 -62
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/UserDatabaseRealm.java
Index: UserDatabaseRealm.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/realm/UserDatabaseRealm.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- UserDatabaseRealm.java 26 Aug 2004 21:37:21 -0000 1.10
+++ UserDatabaseRealm.java 27 Nov 2004 18:29:44 -0000 1.11
@@ -19,7 +19,6 @@
import java.security.Principal;
-import java.util.ArrayList;
import java.util.Iterator;
import javax.naming.Context;
import org.apache.catalina.LifecycleException;
@@ -126,74 +125,44 @@
// --------------------------------------------------------- Public
Methods
-
/**
- * Return the Principal associated with the specified username and
- * credentials, if there is one; otherwise return <code>null</code>.
+ * Return <code>true</code> if the specified Principal has the specified
+ * security role, within the context of this Realm; otherwise return
+ * <code>false</code>. This implementation returns <code>true</code>
+ * if the <code>User</code> has the role, or if any <code>Group</code>
+ * that the <code>User</code> is a member of has the role.
*
- * @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) {
-
- // Does a user with this username exist?
- User user = database.findUser(username);
- if (user == null) {
- return (null);
- }
-
- // Do the credentials specified by the user match?
- // FIXME - Update all realms to support encoded passwords
- boolean validated = false;
- if (hasMessageDigest()) {
- // Hex hashes should be compared case-insensitive
- validated = (digest(credentials)
- .equalsIgnoreCase(user.getPassword()));
- } else {
- validated =
- (digest(credentials).equals(user.getPassword()));
- }
- if (!validated) {
- if (debug >= 2) {
- log(sm.getString("userDatabaseRealm.authenticateFailure",
- username));
- }
- return (null);
- }
-
- // Construct a GenericPrincipal that represents this user
- if (debug >= 2) {
- log(sm.getString("userDatabaseRealm.authenticateSuccess",
- username));
+ * @param principal Principal for whom the role is to be checked
+ * @param role Security role to be checked
+ */
+ public boolean hasRole(Principal principal, String role) {
+ if(! (principal instanceof User) ) {
+ //Play nice with SSO and mixed Realms
+ return super.hasRole(principal, role);
+ }
+ if("*".equals(role)) {
+ return true;
+ } else if(role == null) {
+ return false;
+ }
+ User user = (User)principal;
+ Role dbrole = database.findRole(role);
+ if(dbrole == null) {
+ return false;
}
- ArrayList combined = new ArrayList();
- Iterator roles = user.getRoles();
- while (roles.hasNext()) {
- Role role = (Role) roles.next();
- String rolename = role.getRolename();
- if (!combined.contains(rolename)) {
- combined.add(rolename);
- }
+ if(user.isInRole(dbrole)) {
+ return true;
}
Iterator groups = user.getGroups();
- while (groups.hasNext()) {
- Group group = (Group) groups.next();
- roles = group.getRoles();
- while (roles.hasNext()) {
- Role role = (Role) roles.next();
- String rolename = role.getRolename();
- if (!combined.contains(rolename)) {
- combined.add(rolename);
- }
+ while(groups.hasNext()) {
+ Group group = (Group)groups.next();
+ if(group.isInRole(dbrole)) {
+ return true;
}
}
- return (new GenericPrincipal(this, user.getUsername(),
- user.getPassword(), combined));
-
+ return false;
}
-
// ------------------------------------------------------ Protected
Methods
@@ -202,7 +171,7 @@
*/
protected String getName() {
- return (this.name);
+ return (UserDatabaseRealm.name);
}
1.15 +7 -0 jakarta-tomcat-4.0/webapps/tomcat-docs/realm-howto.xml
Index: realm-howto.xml
===================================================================
RCS file: /home/cvs/jakarta-tomcat-4.0/webapps/tomcat-docs/realm-howto.xml,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- realm-howto.xml 21 Aug 2004 12:37:56 -0000 1.14
+++ realm-howto.xml 27 Nov 2004 18:29:44 -0000 1.15
@@ -1271,6 +1271,13 @@
standard output.</li>
</ul>
+<p>If using digested passwords with DIGEST authentication, the cleartext used
+ to generate the digest is different. In the examples above
+ <code>{cleartext-password}</code> must be replaced with
+ <code>{username}:{realm}:{cleartext-password}</code>. For example, in a
+ development environment this might take the form
+ <code>testUser:localhost:8080:testPassword</code>.</p>
+
<p>To use either of the above techniques, the
<code>$CATALINA_HOME/server/lib/catalina.jar</code> file will need to be
on your class path to make the <code>RealmBase</code> class available.</p>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]