This is an automated email from the ASF dual-hosted git repository. michaelo pushed a commit to branch BZ-63681/9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 90624364edd1115cceb47e7bc4ece5828a0e62d2 Author: Michael Osipov <micha...@apache.org> AuthorDate: Wed Aug 21 23:23:19 2019 +0200 BZ 63681: Introduce RealmBase#authenticate(GSSName, GSSCredential) and friends --- java/org/apache/catalina/Realm.java | 13 +++++ java/org/apache/catalina/realm/CombinedRealm.java | 33 +++++++++++++ java/org/apache/catalina/realm/LockOutRealm.java | 13 +++++ java/org/apache/catalina/realm/RealmBase.java | 58 +++++++++++++++++++---- webapps/docs/changelog.xml | 8 ++++ 5 files changed, 115 insertions(+), 10 deletions(-) diff --git a/java/org/apache/catalina/Realm.java b/java/org/apache/catalina/Realm.java index 7785ec2..6f5d2c7 100644 --- a/java/org/apache/catalina/Realm.java +++ b/java/org/apache/catalina/Realm.java @@ -25,6 +25,8 @@ import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSName; /** * A <b>Realm</b> is a read-only facade for an underlying security realm @@ -117,6 +119,17 @@ public interface Realm extends Contained { /** + * Try to authenticate using a {@link GSSName} + * + * @param gssName The {@link GSSName} of the principal to look up + * @param gssCredential The {@link GSSCredential} of the principal, may be + * {@code null} + * @return the associated principal, or {@code null} if there is none + */ + public Principal authenticate(GSSName gssName, GSSCredential gssCredential); + + + /** * Try to authenticate using {@link X509Certificate}s * * @param certs Array of client certificates, with the first one in diff --git a/java/org/apache/catalina/realm/CombinedRealm.java b/java/org/apache/catalina/realm/CombinedRealm.java index 6a73b0f..6bbc238 100644 --- a/java/org/apache/catalina/realm/CombinedRealm.java +++ b/java/org/apache/catalina/realm/CombinedRealm.java @@ -32,6 +32,7 @@ import org.apache.catalina.Realm; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSName; @@ -386,6 +387,38 @@ public class CombinedRealm extends RealmBase { return null; } + /** + * {@inheritDoc} + */ + @Override + public Principal authenticate(GSSName gssName, GSSCredential gssCredential) { + Principal authenticatedUser = null; + String username = gssName.toString(); + + for (Realm realm : realms) { + if (log.isDebugEnabled()) { + log.debug(sm.getString("combinedRealm.authStart", + username, realm.getClass().getName())); + } + + authenticatedUser = realm.authenticate(gssName, gssCredential); + + if (authenticatedUser == null) { + if (log.isDebugEnabled()) { + log.debug(sm.getString("combinedRealm.authFail", + username, realm.getClass().getName())); + } + } else { + if (log.isDebugEnabled()) { + log.debug(sm.getString("combinedRealm.authSuccess", + username, realm.getClass().getName())); + } + break; + } + } + return authenticatedUser; + } + @Override protected String getPassword(String username) { // This method should never be called diff --git a/java/org/apache/catalina/realm/LockOutRealm.java b/java/org/apache/catalina/realm/LockOutRealm.java index aa4820a..28ce315 100644 --- a/java/org/apache/catalina/realm/LockOutRealm.java +++ b/java/org/apache/catalina/realm/LockOutRealm.java @@ -27,6 +27,7 @@ import org.apache.catalina.LifecycleException; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSName; @@ -200,6 +201,18 @@ public class LockOutRealm extends CombinedRealm { return null; } + /** + * {@inheritDoc} + */ + @Override + public Principal authenticate(GSSName gssName, GSSCredential gssCredential) { + String username = gssName.toString(); + + Principal authenticatedUser = super.authenticate(gssName, gssCredential); + + return filterLockedAccounts(username, authenticatedUser); + } + /* * Filters authenticated principals to ensure that <code>null</code> is diff --git a/java/org/apache/catalina/realm/RealmBase.java b/java/org/apache/catalina/realm/RealmBase.java index aa542a7..91b468f 100644 --- a/java/org/apache/catalina/realm/RealmBase.java +++ b/java/org/apache/catalina/realm/RealmBase.java @@ -497,16 +497,7 @@ public abstract class RealmBase extends LifecycleMBeanBase implements Realm { } } - String name = gssName.toString(); - - if (isStripRealmForGss()) { - int i = name.indexOf('@'); - if (i > 0) { - // Zero so we don't leave a zero length name - name = name.substring(0, i); - } - } - return getPrincipal(name, gssCredential); + return getPrincipal(gssName, gssCredential); } } else { log.error(sm.getString("realmBase.gssContextNotEstablished")); @@ -518,6 +509,19 @@ public abstract class RealmBase extends LifecycleMBeanBase implements Realm { /** + * {@inheritDoc} + */ + @Override + public Principal authenticate(GSSName gssName, GSSCredential gssCredential) { + if (gssName == null) { + return null; + } + + return getPrincipal(gssName, gssCredential); + } + + + /** * Execute a periodic task, such as reloading, etc. This method will be * invoked inside the classloading context of this container. Unexpected * throwables will be caught and logged. @@ -1220,6 +1224,11 @@ public abstract class RealmBase extends LifecycleMBeanBase implements Realm { protected abstract Principal getPrincipal(String username); + /** + * @deprecated This will be removed in Tomcat 10 onwards. Use + * {@link #getPrincipal(GSSName, GSSCredential)} instead. + */ + @Deprecated protected Principal getPrincipal(String username, GSSCredential gssCredential) { Principal p = getPrincipal(username); @@ -1231,6 +1240,35 @@ public abstract class RealmBase extends LifecycleMBeanBase implements Realm { return p; } + + /** + * Get the principal associated with the specified {@link GSSName}. + * + * @param gssName The GSS name + * @param gssCredential the GSS credential of the principal + * @return the principal associated with the given user name. + */ + protected Principal getPrincipal(GSSName gssName, GSSCredential gssCredential) { + String name = gssName.toString(); + + if (isStripRealmForGss()) { + int i = name.indexOf('@'); + if (i > 0) { + // Zero so we don't leave a zero length name + name = name.substring(0, i); + } + } + + Principal p = getPrincipal(name); + + if (p instanceof GenericPrincipal) { + ((GenericPrincipal) p).setGssCredential(gssCredential); + } + + return p; + } + + /** * Return the Server object that is the ultimate parent for the container * with which this Realm is associated. If the server cannot be found (eg diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 8ed612f..ceaa551 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -45,6 +45,14 @@ issues do not "pop up" wrt. others). --> <section name="Tomcat 9.0.30 (markt)" rtext="in development"> + <subsection name="Catalina"> + <changelog> + <add> + <bug>63681</bug>: Introduce RealmBase#authenticate(GSSName, GSSCredential) + and friends. (michaelo) + </add> + </changelog> + </subsection> <subsection name="Coyote"> <changelog> <fix> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org