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 2010/10/08 16:02:06 UTC

svn commit: r1005834 - in /tomcat/trunk: java/org/apache/catalina/ java/org/apache/catalina/authenticator/ java/org/apache/catalina/connector/ java/org/apache/catalina/realm/ webapps/docs/

Author: markt
Date: Fri Oct  8 14:02:05 2010
New Revision: 1005834

URL: http://svn.apache.org/viewvc?rev=1005834&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50016
Re-factor isUserInRole() and login() / logout() methods to support JACC implementations and to improve encapsulation.
Patch provided by David Jencks. 

Modified:
    tomcat/trunk/java/org/apache/catalina/Authenticator.java
    tomcat/trunk/java/org/apache/catalina/Realm.java
    tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java
    tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java
    tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
    tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java
    tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties
    tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java
    tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java
    tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties
    tomcat/trunk/java/org/apache/catalina/connector/Request.java
    tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java
    tomcat/trunk/java/org/apache/catalina/realm/UserDatabaseRealm.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/Authenticator.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Authenticator.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Authenticator.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Authenticator.java Fri Oct  8 14:02:05 2010
@@ -19,8 +19,8 @@
 package org.apache.catalina;
 
 import java.io.IOException;
-import java.security.Principal;
 
+import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.catalina.connector.Request;
@@ -53,21 +53,8 @@ public interface Authenticator {
     public boolean authenticate(Request request, HttpServletResponse response,
             LoginConfig config) throws IOException;
     
-    /**
-     * Register an authenticated Principal and authentication type in our
-     * request, in the current session (if there is one), and with our
-     * SingleSignOn valve, if there is one.  Set the appropriate cookie
-     * to be returned. Passing in a null principal will de-register any
-     * SSO sessions.
-     *
-     * @param request The servlet request we are processing
-     * @param response The servlet response we are populating
-     * @param principal The authenticated Principal to be registered
-     * @param authType The authentication type to be registered
-     * @param username Username used to authenticate (if any)
-     * @param password Password used to authenticate (if any)
-     */
-    public void register(Request request, HttpServletResponse response,
-            Principal principal, String authType,
-            String username, String password);
+    public void login(String userName, String password, Request request)
+            throws ServletException;
+
+    public void logout(Request request) throws ServletException;
 }

Modified: tomcat/trunk/java/org/apache/catalina/Realm.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Realm.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Realm.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Realm.java Fri Oct  8 14:02:05 2010
@@ -158,10 +158,11 @@ public interface Realm {
      * security role, within the context of this Realm; otherwise return
      * <code>false</code>.
      *
+     * @param wrapper wrapper context for evaluating role
      * @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);
+    public boolean hasRole(Wrapper wrapper, Principal principal, String role);
 
         /**
      * Enforce any user data constraint required by the security constraint

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java Fri Oct  8 14:02:05 2010
@@ -829,6 +829,29 @@ public abstract class AuthenticatorBase 
 
     }
 
+    public void login(String username, String password, Request request)
+            throws ServletException {
+        Principal principal = doLogin(request, username, password);
+        register(request, request.getResponse(), principal,
+                    getAuthMethod(), username, password);
+    }
+
+    protected abstract String getAuthMethod();
+
+    protected Principal doLogin(Request request, String username,
+            String password) throws ServletException {
+        Principal p = context.getRealm().authenticate(username, password);
+        if (p == null) {
+            throw new ServletException(sm.getString("authenticator.loginFail"));
+        }
+        return p;
+    }
+
+    public void logout(Request request) throws ServletException {
+        register(request, request.getResponse(), null,
+                null, null, null);
+
+    }
 
     /**
      * Start this component and implement the requirements

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/BasicAuthenticator.java Fri Oct  8 14:02:05 2010
@@ -177,4 +177,8 @@ public class BasicAuthenticator
     }
 
 
+    @Override
+    protected String getAuthMethod() {
+        return Constants.BASIC_METHOD;
+    }
 }

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/DigestAuthenticator.java Fri Oct  8 14:02:05 2010
@@ -198,6 +198,12 @@ public class DigestAuthenticator
     }
 
 
+    @Override
+    protected String getAuthMethod() {
+        return Constants.DIGEST_METHOD;
+    }
+
+
     // ------------------------------------------------------ Protected Methods
 
 

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/FormAuthenticator.java Fri Oct  8 14:02:05 2010
@@ -300,6 +300,12 @@ public class FormAuthenticator
     }
 
 
+    @Override
+    protected String getAuthMethod() {
+        return Constants.FORM_METHOD;
+    }
+
+
     // ------------------------------------------------------ Protected Methods
 
 

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/LocalStrings.properties Fri Oct  8 14:02:05 2010
@@ -17,6 +17,7 @@ authenticator.certificates=No client cer
 authenticator.forbidden=Access to the requested resource has been denied
 authenticator.formlogin=Invalid direct reference to form login page
 authenticator.invalid=Invalid client certificate chain in this request
+authenticator.loginFail=Login failed
 authenticator.keystore=Exception loading key store
 authenticator.manager=Exception initializing trust managers
 authenticator.notAuthenticated=Configuration error:  Cannot perform access control without an authenticated principal

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/NonLoginAuthenticator.java Fri Oct  8 14:02:05 2010
@@ -103,4 +103,8 @@ public final class NonLoginAuthenticator
     }
 
 
+    @Override
+    protected String getAuthMethod() {
+        return "NONE";
+    }
 }

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java Fri Oct  8 14:02:05 2010
@@ -161,4 +161,10 @@ public class SSLAuthenticator
         return (true);
 
     }
+
+
+    @Override
+    protected String getAuthMethod() {
+        return Constants.CERT_METHOD;
+    }
 }

Modified: tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/LocalStrings.properties Fri Oct  8 14:02:05 2010
@@ -61,8 +61,6 @@ coyoteRequest.postTooLarge=Parameters we
 coyoteRequest.chunkedPostTooLarge=Parameters were not parsed because the size of the posted data was too big. Because this request was a chunked request, it could not be processed further. Use the maxPostSize attribute of the connector to resolve this if the application should accept large POSTs.
 coyoteRequest.alreadyAuthenticated=This is request has already been authenticated
 coyoteRequest.noLoginConfig=No authentication mechanism has been configured for this context
-coyoteRequest.noPasswordLogin=The authentication mechanism configured for this context does not support user name and password authentication
-coyoteRequest.authFail=The authentication of user {0} was not successful
 coyoteRequest.authenticate.ise=Cannot call authenticate() after the reponse has been committed
 coyoteRequest.uploadLocationInvalid=The temporary upload location [{0}] is not valid
 

Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Fri Oct  8 14:02:05 2010
@@ -2325,15 +2325,8 @@ public class Request
         if (realm == null)
             return false;
 
-        // Check for a role alias defined in a <security-role-ref> element
-        if (wrapper != null) {
-            String realRole = wrapper.findSecurityReference(role);
-            if ((realRole != null) && realm.hasRole(userPrincipal, realRole))
-                return true;
-        }
-
         // Check for a role defined directly as a <security-role>
-        return (realm.hasRole(userPrincipal, role));
+        return (realm.hasRole(wrapper, userPrincipal, role));
     }
 
 
@@ -2499,31 +2492,11 @@ public class Request
                     sm.getString("coyoteRequest.alreadyAuthenticated"));
         }
         
-        LoginConfig config = context.getLoginConfig();
-        if (config == null) {
-            throw new ServletException(
-                    sm.getString("coyoteRequest.noLoginConfig"));
+        if (context.getAuthenticator() == null) {
+            throw new ServletException("no authenticator");
         }
         
-        String authMethod = config.getAuthMethod();
-        if (BASIC_AUTH.equals(authMethod) || FORM_AUTH.equals(authMethod) ||
-                DIGEST_AUTH.equals(authMethod)) {
-            // Methods support user name and password authentication
-            Realm realm = context.getRealm();
-            
-            Principal principal = realm.authenticate(username, password);
-
-            if (principal == null) {
-                throw new ServletException(
-                        sm.getString("coyoteRequest.authFail", username));
-            }
-            // Assume if we have a non-null LoginConfig then we must have an
-            // authenticator
-            context.getAuthenticator().register(this, getResponse(), principal,
-                    authMethod, username, password);
-        } else {
-            throw new ServletException("coyoteRequest.noPasswordLogin");
-        }
+        context.getAuthenticator().login(username, password, this);
     }
 
     /**
@@ -2531,8 +2504,7 @@ public class Request
      */
     @Override
     public void logout() throws ServletException {
-        context.getAuthenticator().register(this, getResponse(), null,
-                null, null, null);
+        context.getAuthenticator().logout(this);
     }
     
     /**

Modified: tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java (original)
+++ tomcat/trunk/java/org/apache/catalina/realm/RealmBase.java Fri Oct  8 14:02:05 2010
@@ -40,6 +40,7 @@ import org.apache.catalina.LifecycleStat
 import org.apache.catalina.Realm;
 import org.apache.catalina.Server;
 import org.apache.catalina.Service;
+import org.apache.catalina.Wrapper;
 import org.apache.catalina.connector.Request;
 import org.apache.catalina.connector.Response;
 import org.apache.catalina.core.ApplicationSessionCookieConfig;
@@ -763,7 +764,7 @@ public abstract class RealmBase extends 
                     log.debug("  No user authenticated, cannot grant access");
             } else {
                 for (int j = 0; j < roles.length; j++) {
-                    if (hasRole(principal, roles[j])) {
+                    if (hasRole(null, principal, roles[j])) {
                         status = true;
                         if( log.isDebugEnabled() )
                             log.debug( "Role found:  " + roles[j]);
@@ -828,7 +829,14 @@ public abstract class RealmBase extends 
      * @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) {
+    @Override
+    public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
+        // Check for a role alias defined in a <security-role-ref> element
+        if (wrapper != null) {
+            String realRole = wrapper.findSecurityReference(role);
+            if (realRole != null)
+                role = realRole;
+        }
 
         // Should be overridden in JAASRealm - to avoid pretty inefficient conversions
         if ((principal == null) || (role == null) ||

Modified: tomcat/trunk/java/org/apache/catalina/realm/UserDatabaseRealm.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/realm/UserDatabaseRealm.java?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/realm/UserDatabaseRealm.java (original)
+++ tomcat/trunk/java/org/apache/catalina/realm/UserDatabaseRealm.java Fri Oct  8 14:02:05 2010
@@ -31,6 +31,7 @@ import org.apache.catalina.LifecycleExce
 import org.apache.catalina.Role;
 import org.apache.catalina.User;
 import org.apache.catalina.UserDatabase;
+import org.apache.catalina.Wrapper;
 import org.apache.catalina.core.StandardServer;
 import org.apache.catalina.util.LifecycleBase;
 import org.apache.tomcat.util.ExceptionUtils;
@@ -136,7 +137,13 @@ public class UserDatabaseRealm
      * @param role Security role to be checked
      */
     @Override
-    public boolean hasRole(Principal principal, String role) {
+    public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
+        // Check for a role alias defined in a <security-role-ref> element
+        if (wrapper != null) {
+            String realRole = wrapper.findSecurityReference(role);
+            if (realRole != null)
+                role = realRole;
+        }
         if( principal instanceof GenericPrincipal) {
             GenericPrincipal gp = (GenericPrincipal)principal;
             if(gp.getUserPrincipal() instanceof User) {
@@ -145,7 +152,7 @@ public class UserDatabaseRealm
         }
         if(! (principal instanceof User) ) {
             //Play nice with SSO and mixed Realms
-            return super.hasRole(principal, role);
+            return super.hasRole(null, principal, role);
         }
         if("*".equals(role)) {
             return true;

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1005834&r1=1005833&r2=1005834&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Fri Oct  8 14:02:05 2010
@@ -94,6 +94,11 @@
         make extensions, such as JACC implementations, simpler. Patch provided
         by David Jencks. (markt) 
       </fix>
+      <fix>
+        <bug>50016</bug>: Re-factor <code>isUserInRole()</code> and
+        <code>login()/logout()</code> methods to support JACC implementations
+        and to improve encapsulation. Patch provided by David Jencks. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org