You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by lq...@apache.org on 2016/05/31 15:13:50 UTC

svn commit: r1746288 - in /qpid/java/trunk/broker-plugins: amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/

Author: lquack
Date: Tue May 31 15:13:50 2016
New Revision: 1746288

URL: http://svn.apache.org/viewvc?rev=1746288&view=rev
Log:
QPID-7116: [Java Broker] AMQP 1.0 and SaslServlet now use subjectCreator for authentication

before they were using saslServer directly.
This was going to be problamatic when we want to augment the subject with group principals.
All code paths should now be using the subjectCreator

Modified:
    qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java
    qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/SaslServerProvider.java
    qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java

Modified: qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java?rev=1746288&r1=1746287&r2=1746288&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java Tue May 31 15:13:50 2016
@@ -95,7 +95,8 @@ import org.apache.qpid.server.protocol.v
 import org.apache.qpid.server.protocol.v1_0.type.transport.Transfer;
 import org.apache.qpid.server.security.SubjectCreator;
 import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
-import org.apache.qpid.server.security.auth.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
 import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager;
 import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManagerImpl;
 import org.apache.qpid.server.store.StoreException;
@@ -153,6 +154,7 @@ public class AMQPConnection_1_0 extends
     private FrameWriter _frameWriter;
     private ProtocolHandler _frameHandler;
     private volatile boolean _transportBlockedForWriting;
+    private volatile SubjectAuthenticationResult _successfulAuthenticationResult;
 
     private enum FrameReceivingState
     {
@@ -179,8 +181,6 @@ public class AMQPConnection_1_0 extends
     private long _connectionId;
 
     private Container _container;
-    private volatile Principal _user;
-
 
     private int _channelMax = DEFAULT_CHANNEL_MAX;
     private int _maxFrameSize = 4096;
@@ -756,11 +756,6 @@ public class AMQPConnection_1_0 extends
                 }
                 else
                 {
-                    final Principal user = _user;
-                    if (user != null)
-                    {
-                        setUserPrincipal(user);
-                    }
                     if (AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(getSubject()) == null)
                     {
                         closeWithError(AmqpError.NOT_ALLOWED, "Connection has not been authenticated");
@@ -888,11 +883,6 @@ public class AMQPConnection_1_0 extends
         _remoteAddress = remoteAddress;
     }
 
-    public Principal getUser()
-    {
-        return _user;
-    }
-
     public void setProperties(final Map<Symbol, Object> properties)
     {
         _properties = properties;
@@ -918,44 +908,44 @@ public class AMQPConnection_1_0 extends
         }
         catch (SaslException e)
         {
-            handleSaslException();
+            handleSaslError();
         }
     }
 
     private void processSaslResponse(final byte[] response)
     {
-        try
+        byte[] challenge = null;
+        SubjectAuthenticationResult authenticationResult = _successfulAuthenticationResult;
+        if (authenticationResult == null)
         {
-            byte[] challenge = null;
-            if (_user == null)
-            {
-                challenge = _saslServer.evaluateResponse(response != null ? response : new byte[0]);
-            }
+            authenticationResult = _subjectCreator.authenticate(_saslServer, response != null ? response : new byte[0]);
+            challenge = authenticationResult.getChallenge();
+        }
 
-            if (_saslServer.isComplete())
+        if (authenticationResult.getStatus() == AuthenticationResult.AuthenticationStatus.SUCCESS)
+        {
+            _successfulAuthenticationResult = authenticationResult;
+            if (challenge == null || challenge.length == 0)
             {
-                _user = _saslServerProvider.getAuthenticatedPrincipal(_saslServer);
-                if (challenge == null || challenge.length == 0)
-                {
-                    SaslOutcome outcome = new SaslOutcome();
-                    outcome.setCode(SaslCode.OK);
-                    send(new SASLFrame(outcome), null);
-                    _saslComplete = true;
-                    _frameReceivingState = FrameReceivingState.AMQP_HEADER;
-                }
-                else
-                {
-                    continueSaslNegotiation(challenge);
-                }
+                setSubject(_successfulAuthenticationResult.getSubject());
+                SaslOutcome outcome = new SaslOutcome();
+                outcome.setCode(SaslCode.OK);
+                send(new SASLFrame(outcome), null);
+                _saslComplete = true;
+                _frameReceivingState = FrameReceivingState.AMQP_HEADER;
             }
             else
             {
                 continueSaslNegotiation(challenge);
             }
         }
-        catch (SaslException e)
+        else if(authenticationResult.getStatus() == AuthenticationResult.AuthenticationStatus.CONTINUE)
+        {
+            continueSaslNegotiation(challenge);
+        }
+        else
         {
-            handleSaslException();
+            handleSaslError();
         }
     }
 
@@ -968,7 +958,7 @@ public class AMQPConnection_1_0 extends
         _frameReceivingState = FrameReceivingState.SASL_RESPONSE_ONLY;
     }
 
-    private void handleSaslException()
+    private void handleSaslError()
     {
         SaslOutcome outcome = new SaslOutcome();
         outcome.setCode(SaslCode.AUTH);
@@ -1134,12 +1124,6 @@ public class AMQPConnection_1_0 extends
             {
                 return subjectCreator.createSaslServer(mechanism, fqdn, network.getPeerPrincipal());
             }
-
-            @Override
-            public Principal getAuthenticatedPrincipal(SaslServer server)
-            {
-                return new AuthenticatedPrincipal(new UsernamePrincipal(server.getAuthorizationID()));
-            }
         };
     }
 

Modified: qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/SaslServerProvider.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/SaslServerProvider.java?rev=1746288&r1=1746287&r2=1746288&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/SaslServerProvider.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/SaslServerProvider.java Tue May 31 15:13:50 2016
@@ -20,12 +20,10 @@
 package org.apache.qpid.server.protocol.v1_0;
 
 
-import java.security.Principal;
 import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslServer;
 
 public interface SaslServerProvider
 {
     SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException;
-    Principal getAuthenticatedPrincipal(SaslServer server);
 }

Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java?rev=1746288&r1=1746287&r2=1746288&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java Tue May 31 15:13:50 2016
@@ -29,7 +29,6 @@ import java.util.Map;
 import java.util.Random;
 
 import javax.security.auth.Subject;
-import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslServer;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
@@ -42,10 +41,11 @@ import org.slf4j.LoggerFactory;
 
 import org.apache.qpid.server.management.plugin.HttpManagementConfiguration;
 import org.apache.qpid.server.management.plugin.HttpManagementUtil;
-import org.apache.qpid.server.management.plugin.servlet.ServletConnectionPrincipal;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.security.SubjectCreator;
 import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
 import org.apache.qpid.server.util.ConnectionScopedRuntimeException;
 
 public class SaslServlet extends AbstractServlet
@@ -210,75 +210,58 @@ public class SaslServlet extends Abstrac
                                       final HttpServletResponse response,
                                       final HttpSession session, final String saslResponse, final SaslServer saslServer, SubjectCreator subjectCreator) throws IOException
     {
-        final String id;
-        byte[] challenge;
-        try
-        {
-            challenge  = saslServer.evaluateResponse(saslResponse == null
-                                                             ? new byte[0]
-                                                             : DatatypeConverter.parseBase64Binary(saslResponse));
-        }
-        catch(SaslException e)
-        {
-            session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
-            session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER, request));
-            session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request));
-            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
-
-            return;
-        }
+        byte[] saslResponseBytes = saslResponse == null
+                ? new byte[0]
+                : DatatypeConverter.parseBase64Binary(saslResponse);
+        SubjectAuthenticationResult authenticationResult = subjectCreator.authenticate(saslServer, saslResponseBytes);
+        byte[] challenge = authenticationResult.getChallenge();
+        Map<String, Object> outputObject = new LinkedHashMap<>();
+        int responseStatus;
 
-        if(saslServer.isComplete())
+        if (authenticationResult.getStatus() == AuthenticationResult.AuthenticationStatus.SUCCESS)
         {
-            Subject originalSubject = subjectCreator.createSubjectWithGroups(new AuthenticatedPrincipal(saslServer.getAuthorizationID()));
-            Subject subject = new Subject(false,
-                                          originalSubject.getPrincipals(),
-                                          originalSubject.getPublicCredentials(),
-                                          originalSubject.getPrivateCredentials());
-            subject.getPrincipals().add(new ServletConnectionPrincipal(request));
-            subject.setReadOnly();
-
+            Subject subject = authenticationResult.getSubject();
             Broker broker = getBroker();
             try
             {
                 HttpManagementUtil.assertManagementAccess(broker.getSecurityManager(), subject);
+
+                HttpManagementUtil.saveAuthorisedSubject(request, subject);
+                session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
+                session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER, request));
+                session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request));
+                if(challenge != null && challenge.length != 0)
+                {
+                    outputObject.put("challenge", DatatypeConverter.printBase64Binary(challenge));
+                }
+                responseStatus = HttpServletResponse.SC_OK;
             }
             catch(SecurityException e)
             {
-                sendError(response, HttpServletResponse.SC_FORBIDDEN);
-                return;
+                responseStatus = HttpServletResponse.SC_FORBIDDEN;
             }
-
-            HttpManagementUtil.saveAuthorisedSubject(request, subject);
-            session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
-            session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER, request));
-            session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request));
-            if(challenge != null && challenge.length != 0)
-            {
-                Map<String, Object> outputObject = new LinkedHashMap<String, Object>();
-                outputObject.put("challenge", DatatypeConverter.printBase64Binary(challenge));
-
-                sendJsonResponse(outputObject, request, response);
-            }
-
-            response.setStatus(HttpServletResponse.SC_OK);
         }
-        else
+        else if (authenticationResult.getStatus() == AuthenticationResult.AuthenticationStatus.CONTINUE)
         {
             Random rand = getRandom(request);
-            id = String.valueOf(rand.nextLong());
+            String id = String.valueOf(rand.nextLong());
             session.setAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request), id);
             session.setAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER, request), saslServer);
             session.setAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request), System.currentTimeMillis() + SASL_EXCHANGE_EXPIRY);
 
-            response.setStatus(HttpServletResponse.SC_OK);
-
-            Map<String, Object> outputObject = new LinkedHashMap<String, Object>();
             outputObject.put("id", id);
             outputObject.put("challenge", DatatypeConverter.printBase64Binary(challenge));
-
-            sendJsonResponse(outputObject, request, response);
+            responseStatus = HttpServletResponse.SC_OK;
         }
+        else
+        {
+            session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
+            session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER, request));
+            session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request));
+            responseStatus = HttpServletResponse.SC_UNAUTHORIZED;
+        }
+
+        sendJsonResponse(outputObject, request, response, responseStatus, false);
     }
 
     private SubjectCreator getSubjectCreator(HttpServletRequest request)



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org