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 13:38:51 UTC

svn commit: r1746273 - in /qpid/java/trunk: broker-core/src/main/java/org/apache/qpid/server/security/auth/ broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/o...

Author: lquack
Date: Tue May 31 13:38:50 2016
New Revision: 1746273

URL: http://svn.apache.org/viewvc?rev=1746273&view=rev
Log:
QPID-7282: [Java Broker] AMQP Protocol layer now detects final SASL challenge directly instead of relying on AuthenticationResultStatus

Before, AuthenticationResult status was set to CONTINUE if the SASL negotiation completed but there was a final challenge.
Now, AuthenticationResult status reflects the SASL negotiation status and the AMQP layer detects the presence of a final challenge and issues one more AMQP authentication negotiation

Modified:
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ConfigModelPasswordManagingAuthenticationProvider.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java
    qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java
    qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationProviderTest.java
    qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java
    qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java
    qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Impl.java
    qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java Tue May 31 13:38:50 2016
@@ -72,10 +72,15 @@ public class AuthenticationResult
 
     public AuthenticationResult(Principal mainPrincipal)
     {
-        this(mainPrincipal, Collections.<Principal>emptySet());
+        this(mainPrincipal, null);
     }
 
-    public AuthenticationResult(Principal mainPrincipal, Set<Principal> otherPrincipals)
+    public AuthenticationResult(Principal mainPrincipal, byte[] challenge)
+    {
+        this(mainPrincipal, Collections.<Principal>emptySet(), challenge);
+    }
+
+    public AuthenticationResult(Principal mainPrincipal, Set<Principal> otherPrincipals, byte[] challenge)
     {
         AuthenticatedPrincipal specialQpidAuthenticatedPrincipal = new AuthenticatedPrincipal(mainPrincipal);
         _principals.addAll(otherPrincipals);
@@ -84,7 +89,7 @@ public class AuthenticationResult
         _mainPrincipal = mainPrincipal;
 
         _status = AuthenticationStatus.SUCCESS;
-        _challenge = null;
+        _challenge = challenge;
         _cause = null;
     }
 

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ConfigModelPasswordManagingAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ConfigModelPasswordManagingAuthenticationProvider.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ConfigModelPasswordManagingAuthenticationProvider.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ConfigModelPasswordManagingAuthenticationProvider.java Tue May 31 13:38:50 2016
@@ -218,18 +218,13 @@ public abstract class ConfigModelPasswor
     {
         try
         {
-            if (server.isComplete())
-            {
-                return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID()));
-            }
-
             // Process response from the client
             byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
 
-            if (server.isComplete() && (challenge == null || challenge.length == 0))
+            if (server.isComplete())
             {
                 final String userId = server.getAuthorizationID();
-                return new AuthenticationResult(new UsernamePrincipal(userId));
+                return new AuthenticationResult(new UsernamePrincipal(userId), challenge);
             }
             else
             {

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java Tue May 31 13:38:50 2016
@@ -78,17 +78,12 @@ public class KerberosAuthenticationManag
     {
         try
         {
-            if (server.isComplete())
-            {
-                return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID()));
-            }
-
             // Process response from the client
             byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
 
-            if (server.isComplete() && (challenge == null || challenge.length == 0))
+            if (server.isComplete())
             {
-                return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID()));
+                return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID()), challenge);
             }
             else
             {

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java Tue May 31 13:38:50 2016
@@ -210,18 +210,12 @@ public abstract class PrincipalDatabaseA
     {
         try
         {
-            if (server.isComplete())
-            {
-                return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID()));
-            }
-
-            // Process response from the client
             byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
 
-            if (server.isComplete() && (challenge == null || challenge.length == 0))
+            if (server.isComplete())
             {
                 final String userId = server.getAuthorizationID();
-                return new AuthenticationResult(new UsernamePrincipal(userId));
+                return new AuthenticationResult(new UsernamePrincipal(userId), challenge);
             }
             else
             {

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java Tue May 31 13:38:50 2016
@@ -128,20 +128,15 @@ public class SimpleAuthenticationManager
     {
         try
         {
-            if (server.isComplete())
-            {
-                return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID()));
-            }
-
             // Process response from the client
             byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
 
-            if (server.isComplete() && (challenge == null || challenge.length == 0))
+            if (server.isComplete())
             {
                 String authorizationID = server.getAuthorizationID();
                 _logger.debug("Authenticated as " + authorizationID);
 
-                return new AuthenticationResult(new UsernamePrincipal(authorizationID));
+                return new AuthenticationResult(new UsernamePrincipal(authorizationID), challenge);
             }
             else
             {

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java Tue May 31 13:38:50 2016
@@ -250,20 +250,15 @@ public class SimpleLDAPAuthenticationMan
     {
         try
         {
-            if (server.isComplete())
-            {
-                return new AuthenticationResult(new UsernamePrincipal(server.getAuthorizationID()));
-            }
-
             // Process response from the client
             byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
 
-            if (server.isComplete() && (challenge == null || challenge.length == 0))
+            if (server.isComplete())
             {
                 String authorizationID = server.getAuthorizationID();
                 _logger.debug("Authenticated as {}", authorizationID);
 
-                return new AuthenticationResult(new UsernamePrincipal(authorizationID));
+                return new AuthenticationResult(new UsernamePrincipal(authorizationID), challenge);
             }
             else
             {

Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/oauth2/OAuth2AuthenticationProviderImpl.java Tue May 31 13:38:50 2016
@@ -53,7 +53,6 @@ import org.apache.qpid.server.model.Mana
 import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.plugin.QpidServiceLoader;
 import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.UsernamePrincipal;
 import org.apache.qpid.server.security.auth.manager.AbstractAuthenticationManager;
 import org.apache.qpid.server.util.ConnectionBuilder;
 import org.apache.qpid.server.util.ParameterizedTypes;
@@ -221,16 +220,10 @@ public class OAuth2AuthenticationProvide
     {
         try
         {
-            if (server.isComplete())
-            {
-                String accessToken = (String) server.getNegotiatedProperty(OAuth2SaslServer.ACCESS_TOKEN_PROPERTY);
-                return authenticateViaAccessToken(accessToken);
-            }
-
             // Process response from the client
             byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
 
-            if (server.isComplete() && (challenge == null || challenge.length == 0))
+            if (server.isComplete())
             {
                 String accessToken = (String) server.getNegotiatedProperty(OAuth2SaslServer.ACCESS_TOKEN_PROPERTY);
                 return authenticateViaAccessToken(accessToken);

Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationProviderTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationProviderTest.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationProviderTest.java (original)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationProviderTest.java Tue May 31 13:38:50 2016
@@ -19,12 +19,8 @@
 package org.apache.qpid.server.security.auth;
 
 
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-
 import java.io.File;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -33,12 +29,23 @@ import java.util.Map;
 import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslServer;
 
-import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.AuthenticationProvider;
-import org.apache.qpid.server.security.auth.manager.*;
-import org.apache.qpid.server.security.auth.manager.oauth2.OAuth2AuthenticationProvider;
-import org.apache.qpid.server.security.auth.manager.oauth2.OAuth2AuthenticationProviderImplFactory;
-import org.apache.qpid.server.security.auth.manager.oauth2.OAuth2IdentityResolverService;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.security.auth.manager.Base64MD5PasswordDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.Base64MD5PasswordDatabaseAuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.KerberosAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.KerberosAuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.MD5AuthenticationProvider;
+import org.apache.qpid.server.security.auth.manager.MD5AuthenticationProviderFactory;
+import org.apache.qpid.server.security.auth.manager.PlainAuthenticationProvider;
+import org.apache.qpid.server.security.auth.manager.PlainAuthenticationProviderFactory;
+import org.apache.qpid.server.security.auth.manager.PlainPasswordDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.PlainPasswordDatabaseAuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.ScramSHA1AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.ScramSHA1AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.ScramSHA256AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.ScramSHA256AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.SimpleAuthenticationManager;
 import org.apache.qpid.server.util.BrokerTestHelper;
 import org.apache.qpid.test.utils.QpidTestCase;
 import org.apache.qpid.test.utils.TestFileUtils;
@@ -114,15 +121,9 @@ public class AuthenticationProviderTest
 
         AuthenticationResult result = authenticationProvider.authenticate(saslServer, new byte[1]);
         assertEquals("Unexpected authentication status " + authenticationProvider,
-                     AuthenticationResult.AuthenticationStatus.CONTINUE,
-                     result.getStatus());
-        assertTrue("Unexpected challenge " + authenticationProvider, Arrays.equals(new byte[1], result.getChallenge()));
-
-        result = authenticationProvider.authenticate(saslServer, new byte[1]);
-        assertEquals("Unexpected authentication status for " + authenticationProvider,
                      AuthenticationResult.AuthenticationStatus.SUCCESS,
                      result.getStatus());
-        assertNull("Unexpected challenge " + authenticationProvider, result.getChallenge());
+        assertTrue("Unexpected challenge " + authenticationProvider, Arrays.equals(new byte[1], result.getChallenge()));
     }
 
 

Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java (original)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/AuthenticationResultTest.java Tue May 31 13:38:50 2016
@@ -87,7 +87,7 @@ public class AuthenticationResultTest ex
         Principal secondaryPrincipal = mock(Principal.class);
         Set<Principal> secondaryPrincipals = Collections.singleton(secondaryPrincipal);
 
-        AuthenticationResult authenticationResult = new AuthenticationResult(mainPrincipal, secondaryPrincipals);
+        AuthenticationResult authenticationResult = new AuthenticationResult(mainPrincipal, secondaryPrincipals, null);
 
         assertOnlyContainsWrappedAndSecondaryPrincipals(mainPrincipal, secondaryPrincipals, authenticationResult.getPrincipals());
         assertSame(AuthenticationResult.AuthenticationStatus.SUCCESS, authenticationResult.getStatus());
@@ -103,7 +103,7 @@ public class AuthenticationResultTest ex
         Set<Principal> deDuplicatedSecondaryPrincipals = Collections.singleton(secondaryPrincipal);
 
         AuthenticationResult authenticationResult = new AuthenticationResult(
-                mainPrincipal, secondaryPrincipalsContainingDuplicateOfMainPrincipal);
+                mainPrincipal, secondaryPrincipalsContainingDuplicateOfMainPrincipal, null);
 
         assertOnlyContainsWrappedAndSecondaryPrincipals(mainPrincipal, deDuplicatedSecondaryPrincipals, authenticationResult.getPrincipals());
 

Modified: qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java Tue May 31 13:38:50 2016
@@ -77,6 +77,7 @@ public class ServerConnectionDelegate ex
     }
 
     private volatile ConnectionState _state = ConnectionState.INIT;
+    private volatile SubjectAuthenticationResult _successfulAuthenticationResult;
 
 
     public ServerConnectionDelegate(Broker<?> broker, String localFQDN, SubjectCreator subjectCreator)
@@ -184,13 +185,28 @@ public class ServerConnectionDelegate ex
     protected void secure(final SaslServer ss, final Connection conn, final byte[] response)
     {
         final ServerConnection sconn = (ServerConnection) conn;
-        final SubjectAuthenticationResult authResult = _subjectCreator.authenticate(ss, response);
+        SubjectAuthenticationResult authResult = _successfulAuthenticationResult;
+        byte[] challenge = null;
+        if (authResult == null)
+        {
+            authResult = _subjectCreator.authenticate(ss, response);
+            challenge = authResult.getChallenge();
+        }
 
         if (AuthenticationStatus.SUCCESS.equals(authResult.getStatus()))
         {
-            tuneAuthorizedConnection(sconn);
-            sconn.setAuthorizedSubject(authResult.getSubject());
-            _state = ConnectionState.AWAIT_TUNE_OK;
+            _successfulAuthenticationResult = authResult;
+            if (challenge == null || challenge.length == 0)
+            {
+                tuneAuthorizedConnection(sconn);
+                sconn.setAuthorizedSubject(authResult.getSubject());
+                _state = ConnectionState.AWAIT_TUNE_OK;
+            }
+            else
+            {
+                connectionAuthContinue(sconn, authResult.getChallenge());
+                _state = ConnectionState.AWAIT_SECURE_OK;
+            }
         }
         else if (AuthenticationStatus.CONTINUE.equals(authResult.getStatus()))
         {

Modified: qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Impl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Impl.java?rev=1746273&r1=1746272&r2=1746273&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Impl.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Impl.java Tue May 31 13:38:50 2016
@@ -164,6 +164,7 @@ public class AMQPConnection_0_8Impl
     private volatile int _currentMethodId;
     private final int _binaryDataLimit;
     private volatile boolean _transportBlockedForWriting;
+    private volatile SubjectAuthenticationResult _successfulAuthenticationResult;
 
     public AMQPConnection_0_8Impl(Broker<?> broker,
                                   ServerNetworkConnection network,
@@ -1046,8 +1047,6 @@ public class AMQPConnection_0_8Impl
 
         assertState(ConnectionState.AWAIT_SECURE_OK);
 
-        Broker<?> broker = getBroker();
-
         SubjectCreator subjectCreator = getSubjectCreator();
 
         SaslServer ss = getSaslServer();
@@ -1055,44 +1054,8 @@ public class AMQPConnection_0_8Impl
         {
             sendConnectionClose(AMQConstant.INTERNAL_ERROR, "No SASL context set up in connection", 0);
         }
-        MethodRegistry methodRegistry = getMethodRegistry();
-        SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, response);
-        switch (authResult.getStatus())
-        {
-            case ERROR:
-                Exception cause = authResult.getCause();
-
-                _logger.debug("Authentication failed: {}", (cause == null ? "" : cause.getMessage()));
 
-                sendConnectionClose(AMQConstant.NOT_ALLOWED, "Authentication failed", 0);
-
-                disposeSaslServer();
-                break;
-            case SUCCESS:
-                _logger.debug("Connected as: {} ", authResult.getSubject());
-
-                int frameMax = getDefaultMaxFrameSize();
-
-                if (frameMax <= 0)
-                {
-                    frameMax = Integer.MAX_VALUE;
-                }
-
-                ConnectionTuneBody tuneBody =
-                        methodRegistry.createConnectionTuneBody(broker.getConnection_sessionCountLimit(),
-                                                                frameMax,
-                                                                broker.getConnection_heartBeatDelay());
-                writeFrame(tuneBody.generateFrame(0));
-                _state = ConnectionState.AWAIT_TUNE_OK;
-                setSubject(authResult.getSubject());
-                disposeSaslServer();
-                break;
-            case CONTINUE:
-
-                ConnectionSecureBody
-                        secureBody = methodRegistry.createConnectionSecureBody(authResult.getChallenge());
-                writeFrame(secureBody.generateFrame(0));
-        }
+        processSaslResponse(response, subjectCreator, ss);
     }
 
 
@@ -1134,8 +1097,6 @@ public class AMQPConnection_0_8Impl
 
         assertState(ConnectionState.AWAIT_START_OK);
 
-        Broker<?> broker = getBroker();
-
         _logger.debug("SASL Mechanism selected: {} Locale : {}", mechanism, locale);
 
         SubjectCreator subjectCreator = getSubjectCreator();
@@ -1158,57 +1119,84 @@ public class AMQPConnection_0_8Impl
 
                 setSaslServer(ss);
 
-                final SubjectAuthenticationResult authResult = subjectCreator.authenticate(ss, response);
+                processSaslResponse(response, subjectCreator, ss);
+            }
+        }
+        catch (SaslException e)
+        {
+            disposeSaslServer();
+            sendConnectionClose(AMQConstant.INTERNAL_ERROR, "SASL error: " + e, 0);
+        }
+    }
 
-                MethodRegistry methodRegistry = getMethodRegistry();
+    private void processSaslResponse(final byte[] response,
+                                     final SubjectCreator subjectCreator,
+                                     final SaslServer ss)
+    {
+        MethodRegistry methodRegistry = getMethodRegistry();
+        SubjectAuthenticationResult authResult = _successfulAuthenticationResult;
+        byte[] challenge = null;
+        if (authResult == null)
+        {
+            authResult = subjectCreator.authenticate(ss, response);
+            challenge = authResult.getChallenge();
+        }
+
+        switch (authResult.getStatus())
+        {
+            case ERROR:
+                Exception cause = authResult.getCause();
 
-                switch (authResult.getStatus())
+                _logger.debug("Authentication failed: {}", (cause == null ? "" : cause.getMessage()));
+
+                sendConnectionClose(AMQConstant.NOT_ALLOWED, "Authentication failed", 0);
+
+                disposeSaslServer();
+                break;
+
+            case SUCCESS:
+                _successfulAuthenticationResult = authResult;
+                if (challenge == null || challenge.length == 0)
                 {
-                    case ERROR:
-                        Exception cause = authResult.getCause();
+                    _logger.debug("Connected as: {}", authResult.getSubject());
+                    setSubject(authResult.getSubject());
 
-                        _logger.debug("Authentication failed: {}", (cause == null ? "" : cause.getMessage()));
+                    int frameMax = getDefaultMaxFrameSize();
 
-                        sendConnectionClose(AMQConstant.NOT_ALLOWED, "Authentication failed", 0);
+                    if (frameMax <= 0)
+                    {
+                        frameMax = Integer.MAX_VALUE;
+                    }
 
-                        disposeSaslServer();
-                        break;
-
-                    case SUCCESS:
-                        _logger.debug("Connected as: {}", authResult.getSubject());
-                        setSubject(authResult.getSubject());
-
-                        int frameMax = getDefaultMaxFrameSize();
-
-                        if (frameMax <= 0)
-                        {
-                            frameMax = Integer.MAX_VALUE;
-                        }
-
-                        ConnectionTuneBody
-                                tuneBody =
-                                methodRegistry.createConnectionTuneBody(broker.getConnection_sessionCountLimit(),
-                                                                        frameMax,
-                                                                        broker.getConnection_heartBeatDelay());
-                        writeFrame(tuneBody.generateFrame(0));
-                        _state = ConnectionState.AWAIT_TUNE_OK;
-                        break;
-                    case CONTINUE:
-                        ConnectionSecureBody
-                                secureBody = methodRegistry.createConnectionSecureBody(authResult.getChallenge());
-                        writeFrame(secureBody.generateFrame(0));
+                    Broker<?> broker = getBroker();
 
-                        _state = ConnectionState.AWAIT_SECURE_OK;
+                    ConnectionTuneBody tuneBody =
+                            methodRegistry.createConnectionTuneBody(broker.getConnection_sessionCountLimit(),
+                                                                    frameMax,
+                                                                    broker.getConnection_heartBeatDelay());
+                    writeFrame(tuneBody.generateFrame(0));
+                    _state = ConnectionState.AWAIT_TUNE_OK;
+                    disposeSaslServer();
                 }
-            }
-        }
-        catch (SaslException e)
-        {
-            disposeSaslServer();
-            sendConnectionClose(AMQConstant.INTERNAL_ERROR, "SASL error: " + e, 0);
+                else
+                {
+                    continueSaslNegotiation(challenge);
+                }
+                break;
+            case CONTINUE:
+                continueSaslNegotiation(challenge);
+                break;
         }
     }
 
+    private void continueSaslNegotiation(final byte[] challenge)
+    {
+        ConnectionSecureBody secureBody = getMethodRegistry().createConnectionSecureBody(challenge);
+        writeFrame(secureBody.generateFrame(0));
+
+        _state = ConnectionState.AWAIT_SECURE_OK;
+    }
+
     @Override
     public void receiveConnectionTuneOk(final int channelMax, final long frameMax, final int heartbeat)
     {

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=1746273&r1=1746272&r2=1746273&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 13:38:50 2016
@@ -179,7 +179,7 @@ public class AMQPConnection_1_0 extends
     private long _connectionId;
 
     private Container _container;
-    private Principal _user;
+    private volatile Principal _user;
 
 
     private int _channelMax = DEFAULT_CHANNEL_MAX;
@@ -396,40 +396,7 @@ public class AMQPConnection_1_0 extends
 
         assertState(FrameReceivingState.SASL_RESPONSE_ONLY);
 
-        try
-        {
-
-            // Process response from the client
-            byte[] challenge = _saslServer.evaluateResponse(response != null ? response : new byte[0]);
-
-            if (_saslServer.isComplete())
-            {
-                SaslOutcome outcome = new SaslOutcome();
-
-                outcome.setCode(SaslCode.OK);
-                send(new SASLFrame(outcome), null);
-                _saslComplete = true;
-                _user = _saslServerProvider.getAuthenticatedPrincipal(_saslServer);
-                _frameReceivingState = FrameReceivingState.AMQP_HEADER;
-            }
-            else
-            {
-                SaslChallenge challengeBody = new SaslChallenge();
-                challengeBody.setChallenge(new Binary(challenge));
-                send(new SASLFrame(challengeBody), null);
-
-            }
-        }
-        catch (SaslException e)
-        {
-            SaslOutcome outcome = new SaslOutcome();
-
-            outcome.setCode(SaslCode.AUTH);
-            send(new SASLFrame(outcome), null);
-            _saslComplete = true;
-            closeSaslWithFailure();
-
-        }
+        processSaslResponse(response);
     }
 
     public AMQPDescribedTypeRegistry getDescribedTypeRegistry()
@@ -947,42 +914,67 @@ public class AMQPConnection_1_0 extends
         try
         {
             _saslServer = _saslServerProvider.getSaslServer(mechanism, "localhost");
+            processSaslResponse(response);
+        }
+        catch (SaslException e)
+        {
+            handleSaslException();
+        }
+    }
 
-            // Process response from the client
-            byte[] challenge = _saslServer.evaluateResponse(response != null ? response : new byte[0]);
+    private void processSaslResponse(final byte[] response)
+    {
+        try
+        {
+            byte[] challenge = null;
+            if (_user == null)
+            {
+                challenge = _saslServer.evaluateResponse(response != null ? response : new byte[0]);
+            }
 
             if (_saslServer.isComplete())
             {
-                SaslOutcome outcome = new SaslOutcome();
-
-                outcome.setCode(SaslCode.OK);
-                send(new SASLFrame(outcome), null);
-                _saslComplete = true;
                 _user = _saslServerProvider.getAuthenticatedPrincipal(_saslServer);
-
-                _frameReceivingState = FrameReceivingState.AMQP_HEADER;
-
+                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);
+                }
             }
             else
             {
-                SaslChallenge challengeBody = new SaslChallenge();
-                challengeBody.setChallenge(new Binary(challenge));
-                send(new SASLFrame(challengeBody), null);
-
-                _frameReceivingState = FrameReceivingState.SASL_RESPONSE_ONLY;
+                continueSaslNegotiation(challenge);
             }
         }
         catch (SaslException e)
         {
-            SaslOutcome outcome = new SaslOutcome();
+            handleSaslException();
+        }
+    }
 
-            outcome.setCode(SaslCode.AUTH);
-            send(new SASLFrame(outcome), null);
-            _saslComplete = true;
+    private void continueSaslNegotiation(final byte[] challenge)
+    {
+        SaslChallenge challengeBody = new SaslChallenge();
+        challengeBody.setChallenge(new Binary(challenge));
+        send(new SASLFrame(challengeBody), null);
 
-            closeSaslWithFailure();
+        _frameReceivingState = FrameReceivingState.SASL_RESPONSE_ONLY;
+    }
 
-        }
+    private void handleSaslException()
+    {
+        SaslOutcome outcome = new SaslOutcome();
+        outcome.setCode(SaslCode.AUTH);
+        send(new SASLFrame(outcome), null);
+        _saslComplete = true;
+        closeSaslWithFailure();
     }
 
     public int getMaxFrameSize()



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