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 2015/06/17 10:47:03 UTC

svn commit: r1685947 - in /tomcat/trunk/java/org/apache/catalina/authenticator/jaspic: JaspicAuthenticator.java JaspicCallbackHandler.java PrincipalGroupCallback.java

Author: markt
Date: Wed Jun 17 08:47:03 2015
New Revision: 1685947

URL: http://svn.apache.org/r1685947
Log:
Removed use of ThreadLocal. Added some Javadoc comments.
Patch provided by fjodorver.

Modified:
    tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java
    tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java
    tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java?rev=1685947&r1=1685946&r2=1685947&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicAuthenticator.java Wed Jun 17 08:47:03 2015
@@ -34,10 +34,14 @@ import javax.servlet.http.HttpServletRes
 import org.apache.catalina.LifecycleException;
 import org.apache.catalina.authenticator.AuthenticatorBase;
 import org.apache.catalina.connector.Request;
-
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 
+/**
+ * Security valve which implements JASPIC authentication
+ * @author Fjodor Vershinin
+ *
+ */
 public class JaspicAuthenticator extends AuthenticatorBase {
 
     private static final Log log = LogFactory.getLog(JaspicAuthenticator.class);
@@ -45,35 +49,44 @@ public class JaspicAuthenticator extends
     private static final String AUTH_TYPE = "JASPIC";
     private static final String MESSAGE_LAYER = "HttpServlet";
 
-    private JaspicCallbackHandler callbackHandler;
     private Subject serviceSubject;
 
     @SuppressWarnings("rawtypes")
     private Map authProperties = null;
 
-
     @Override
     protected synchronized void startInternal() throws LifecycleException {
         super.startInternal();
-        callbackHandler = new JaspicCallbackHandler(container.getRealm());
         serviceSubject = new Subject();
     }
 
-
     @Override
     public boolean authenticate(Request request, HttpServletResponse response) throws IOException {
         MessageInfo messageInfo = new MessageInfoImpl(request, response, true);
+        JaspicCallbackHandler callbackHandler = getJaspicCallbackHandler();
+
         AuthConfigFactory factory = AuthConfigFactory.getFactory();
-        String appContext = request.getLocalName() + " " + request.getContextPath();
+        String appContext = getAppContextId(request);
 
-        AuthConfigProvider configProvider =
-                factory.getConfigProvider(MESSAGE_LAYER, appContext, null);
-        ServerAuthConfig authConfig = getAuthConfig(appContext, configProvider);
-        String authContextId = authConfig.getAuthContextID(messageInfo);
-
-        ServerAuthContext authContext = null;
-        authContext = getAuthContext(authConfig, authContextId, authProperties, authContext);
-        AuthStatus authStatus = validateRequest(messageInfo, authContext);
+        AuthConfigProvider configProvider = factory.getConfigProvider(MESSAGE_LAYER, appContext,
+                null);
+        if (configProvider == null) {
+            handleUnauthorizedRequest(response, null);
+            return false;
+        }
+
+        AuthStatus authStatus;
+        try {
+            ServerAuthConfig authConfig = configProvider.getServerAuthConfig(MESSAGE_LAYER,
+                    appContext, callbackHandler);
+            String messageAuthContextId = authConfig.getAuthContextID(messageInfo);
+            ServerAuthContext authContext = authConfig.getAuthContext(messageAuthContextId,
+                    serviceSubject, authProperties);
+            authStatus = authContext.validateRequest(messageInfo, new Subject(), serviceSubject);
+        } catch (AuthException e) {
+            handleUnauthorizedRequest(response, e);
+            return false;
+        }
 
         if (authStatus == AuthStatus.SUCCESS) {
             Principal principal = callbackHandler.getPrincipal();
@@ -82,52 +95,33 @@ public class JaspicAuthenticator extends
             }
             return true;
         }
-
         return false;
     }
 
-
-    private AuthStatus validateRequest(MessageInfo messageInfo, ServerAuthContext authContext) {
-        Subject clientSubject = new Subject();
-        try {
-            return authContext.validateRequest(messageInfo, clientSubject, serviceSubject);
-        } catch (AuthException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-
-    @SuppressWarnings("rawtypes")
-    private ServerAuthContext getAuthContext(ServerAuthConfig authConfig, String authContextId,
-            Map authProperties, ServerAuthContext authContext) {
-        try {
-            return authConfig.getAuthContext(authContextId, serviceSubject, authProperties);
-        } catch (AuthException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-
     @Override
     public void login(String userName, String password, Request request) throws ServletException {
         throw new IllegalStateException("not implemented yet!");
     }
 
-
     @Override
     public void logout(Request request) {
         throw new IllegalStateException("not implemented yet!");
     }
 
+    private void handleUnauthorizedRequest(HttpServletResponse response, AuthException e)
+            throws IOException {
+        log.error(sm.getString("authenticator.unauthorized"), e);
+        response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
+                sm.getString("authenticator.unauthorized"));
+    }
 
-    private ServerAuthConfig getAuthConfig(String appContext, AuthConfigProvider configProvider) {
-        try {
-            return configProvider.getServerAuthConfig(MESSAGE_LAYER, appContext, callbackHandler);
-        } catch (AuthException e) {
-            throw new IllegalStateException(e);
-        }
+    private String getAppContextId(Request request) {
+        return request.getServletContext().getVirtualServerName() + " " + request.getContextPath();
     }
 
+    private JaspicCallbackHandler getJaspicCallbackHandler() {
+        return new JaspicCallbackHandler(container.getRealm());
+    }
 
     @Override
     protected String getAuthMethod() {

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java?rev=1685947&r1=1685946&r2=1685947&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/JaspicCallbackHandler.java Wed Jun 17 08:47:03 2015
@@ -17,7 +17,6 @@
 package org.apache.catalina.authenticator.jaspic;
 
 import java.io.IOException;
-import java.security.Principal;
 import java.util.Collections;
 
 import javax.security.auth.Subject;
@@ -32,12 +31,17 @@ import org.apache.catalina.Realm;
 import org.apache.catalina.realm.GenericPrincipal;
 import org.apache.tomcat.util.res.StringManager;
 
+/**
+ * Callback handler which converts callbacks to realm
+ * @author Fjodor Vershinin
+ *
+ */
 public class JaspicCallbackHandler implements CallbackHandler {
     protected static final StringManager sm = StringManager.getManager(JaspicCallbackHandler.class);
 
     private Realm realm;
 
-    private ThreadLocal<PrincipalGroupCallback> principalGroupCallback = new ThreadLocal<>();
+    private PrincipalGroupCallback principalGroupCallback = new PrincipalGroupCallback();
 
     public JaspicCallbackHandler(Realm realm) {
         this.realm = realm;
@@ -45,21 +49,24 @@ public class JaspicCallbackHandler imple
 
     @Override
     public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
-        principalGroupCallback.set(new PrincipalGroupCallback());
+        if (callbacks == null) {
+            return;
+        }
         for (Callback callback : callbacks) {
             handleCallback(callback);
         }
     }
 
-    public Principal getPrincipal() {
-        return principalGroupCallback.get().getPrincipal();
+    public GenericPrincipal getPrincipal() {
+        return principalGroupCallback.getPrincipal();
     }
 
     private void handleCallback(Callback callback) {
+
         if (callback instanceof CallerPrincipalCallback) {
-            principalGroupCallback.get().addCallback(callback);
+            principalGroupCallback.setCallerPrincipalCallback((CallerPrincipalCallback) callback);
         } else if (callback instanceof GroupPrincipalCallback) {
-            principalGroupCallback.get().addCallback(callback);
+            principalGroupCallback.setCallerPrincipalCallback((GroupPrincipalCallback) callback);
         } else if (callback instanceof PasswordValidationCallback) {
             handlePasswordValidationCallback((PasswordValidationCallback) callback);
         } else {

Modified: tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java?rev=1685947&r1=1685946&r2=1685947&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java (original)
+++ tomcat/trunk/java/org/apache/catalina/authenticator/jaspic/PrincipalGroupCallback.java Wed Jun 17 08:47:03 2015
@@ -21,27 +21,36 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
-import javax.security.auth.callback.Callback;
 import javax.security.auth.message.callback.CallerPrincipalCallback;
 import javax.security.auth.message.callback.GroupPrincipalCallback;
 
 import org.apache.catalina.realm.GenericPrincipal;
 
+/**
+ * This class merges two principal callbacks into one tomcat's
+ * {@link GenericPrincipal}
+ * @author Fjodor Vershinin
+ *
+ */
 public class PrincipalGroupCallback {
     private CallerPrincipalCallback callerPrincipalCallback;
     private GroupPrincipalCallback groupPrincipalCallback;
 
-    public void addCallback(Callback callback) {
-        if (callback instanceof CallerPrincipalCallback) {
-            callerPrincipalCallback = (CallerPrincipalCallback) callback;
-        }
-        if (callback instanceof GroupPrincipalCallback) {
-            groupPrincipalCallback = (GroupPrincipalCallback) callback;
-        }
+    public void setCallerPrincipalCallback(CallerPrincipalCallback callerPrincipalCallback) {
+        this.callerPrincipalCallback = callerPrincipalCallback;
+    }
+
+    public void setCallerPrincipalCallback(GroupPrincipalCallback groupPrincipalCallback) {
+        this.groupPrincipalCallback = groupPrincipalCallback;
     }
 
-    public Principal getPrincipal() {
-        if (callerPrincipalCallback != null) {
+    /**
+     * Get tomcat's principal, which contains user principal and roles
+     * @return {@link GenericPrincipal}
+     */
+    public GenericPrincipal getPrincipal() {
+        if (callerPrincipalCallback == null) {
+            return null;
         }
         Principal userPrincipal = getUserPrincipal();
         return new GenericPrincipal(getUserName(), null, getRoles(), userPrincipal);



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