You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/04/23 14:39:57 UTC

[shardingsphere] branch master updated: Refactor PostgreSQLAuthenticationEngine (#10163)

This is an automated email from the ASF dual-hosted git repository.

panjuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 3f242ff  Refactor PostgreSQLAuthenticationEngine (#10163)
3f242ff is described below

commit 3f242ff561267a28c7fb6fe94516cb028c7817c3
Author: 吴伟杰 <wu...@apache.org>
AuthorDate: Fri Apr 23 22:39:13 2021 +0800

    Refactor PostgreSQLAuthenticationEngine (#10163)
    
    * Throw exception rather than write response in many places
    
    * Remove unused exception handling
---
 .../constant/PostgreSQLMessageSeverityLevel.java   | 52 +++++++++++++++++++++
 .../netty/FrontendChannelInboundHandler.java       |  3 +-
 .../PostgreSQLAuthenticationEngine.java            | 53 ++++++----------------
 .../PostgreSQLAuthenticationHandler.java           |  3 +-
 ...InvalidAuthorizationSpecificationException.java | 34 ++++++++++++++
 .../PostgreSQLAuthenticationException.java         | 37 +++++++++++++++
 .../PostgreSQLProtocolViolationException.java      | 36 +++++++++++++++
 .../postgresql/err/PostgreSQLErrPacketFactory.java | 31 +++++++++----
 .../PostgreSQLAuthenticationEngineTest.java        |  9 ++--
 9 files changed, 204 insertions(+), 54 deletions(-)

diff --git a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/constant/PostgreSQLMessageSeverityLevel.java b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/constant/PostgreSQLMessageSeverityLevel.java
new file mode 100644
index 0000000..311d2c2
--- /dev/null
+++ b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/constant/PostgreSQLMessageSeverityLevel.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.db.protocol.postgresql.constant;
+
+/**
+ * PostgreSQL message severity level.
+ *
+ * @see <a href="https://www.postgresql.org/docs/12/runtime-config-logging.html#RUNTIME-CONFIG-SEVERITY-LEVELS">Table 19.2. Message Severity Levels</a>
+ */
+public enum PostgreSQLMessageSeverityLevel {
+    
+    DEBUG0,
+    
+    DEBUG1,
+    
+    DEBUG2,
+    
+    DEBUG3,
+    
+    DEBUG4,
+    
+    DEBUG5,
+    
+    INFO,
+    
+    NOTICE,
+    
+    WARNING,
+    
+    ERROR,
+    
+    LOG,
+    
+    FATAL,
+    
+    PANIC
+}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-core/src/main/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandler.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-core/src/main/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandler.java
index d823b97..c0243a9 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-core/src/main/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandler.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-core/src/main/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandler.java
@@ -78,7 +78,8 @@ public final class FrontendChannelInboundHandler extends ChannelInboundHandlerAd
         } catch (final Exception ex) {
             // CHECKSTYLE:ON
             log.error("Exception occur: ", ex);
-            context.write(databaseProtocolFrontendEngine.getCommandExecuteEngine().getErrorPacket(ex));
+            context.writeAndFlush(databaseProtocolFrontendEngine.getCommandExecuteEngine().getErrorPacket(ex));
+            context.close();
         }
         return false;
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
index caaea6d..bcb9912 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
@@ -22,7 +22,6 @@ import io.netty.channel.ChannelHandlerContext;
 import org.apache.shardingsphere.db.protocol.payload.PacketPayload;
 import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLErrorCode;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.BinaryStatementRegistry;
-import org.apache.shardingsphere.db.protocol.postgresql.packet.generic.PostgreSQLErrorResponsePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.generic.PostgreSQLReadyForQueryPacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.handshake.PostgreSQLAuthenticationMD5PasswordPacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.handshake.PostgreSQLAuthenticationOKPacket;
@@ -33,14 +32,13 @@ import org.apache.shardingsphere.db.protocol.postgresql.packet.handshake.Postgre
 import org.apache.shardingsphere.db.protocol.postgresql.packet.handshake.PostgreSQLSSLNegativePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLMessagePacketType;
 import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
-import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationEngine;
 import org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationResult;
 import org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationResultBuilder;
 import org.apache.shardingsphere.proxy.frontend.connection.ConnectionIdGenerator;
-import org.apache.shardingsphere.proxy.frontend.postgresql.err.PostgreSQLErrPacketFactory;
-import org.postgresql.util.PSQLException;
-import org.postgresql.util.ServerErrorMessage;
+import org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.InvalidAuthorizationSpecificationException;
+import org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLAuthenticationException;
+import org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLProtocolViolationException;
 
 /**
  * Authentication engine for PostgreSQL.
@@ -77,55 +75,32 @@ public final class PostgreSQLAuthenticationEngine implements AuthenticationEngin
     private AuthenticationResult processStartupMessage(final ChannelHandlerContext context, final PostgreSQLPacketPayload payload) {
         startupMessageReceived = true;
         PostgreSQLComStartupPacket comStartupPacket = new PostgreSQLComStartupPacket(payload);
-        String database = comStartupPacket.getDatabase();
-        if (!Strings.isNullOrEmpty(database) && !ProxyContext.getInstance().schemaExists(database)) {
-            context.writeAndFlush(createErrorPacket(PostgreSQLErrorCode.INVALID_CATALOG_NAME, String.format("database \"%s\" does not exist", database)));
-            context.close();
-            return AuthenticationResultBuilder.continued();
-        }
         String user = comStartupPacket.getUser();
         if (Strings.isNullOrEmpty(user)) {
-            context.writeAndFlush(createErrorPacket(PostgreSQLErrorCode.SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION, "user not set in StartupMessage"));
-            context.close();
-            return AuthenticationResultBuilder.continued();
+            throw new InvalidAuthorizationSpecificationException("no PostgreSQL user name specified in startup packet");
         }
         md5Salt = PostgreSQLRandomGenerator.getInstance().generateRandomBytes(4);
         context.writeAndFlush(new PostgreSQLAuthenticationMD5PasswordPacket(md5Salt));
-        currentAuthResult = AuthenticationResultBuilder.continued(user, "", database);
+        currentAuthResult = AuthenticationResultBuilder.continued(user, "", comStartupPacket.getDatabase());
         return currentAuthResult;
     }
     
     private AuthenticationResult processPasswordMessage(final ChannelHandlerContext context, final PostgreSQLPacketPayload payload) {
         char messageType = (char) payload.readInt1();
         if (PostgreSQLMessagePacketType.PASSWORD_MESSAGE.getValue() != messageType) {
-            PostgreSQLErrorResponsePacket responsePacket = createErrorPacket(
-                    PostgreSQLErrorCode.SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION, String.format("PasswordMessage is expected, message type 'p', but not '%s'", messageType));
-            context.writeAndFlush(responsePacket);
-            context.close();
-            currentAuthResult = AuthenticationResultBuilder.continued();
-            return currentAuthResult;
+            throw new PostgreSQLProtocolViolationException("password", Character.toString(messageType));
         }
         PostgreSQLPasswordMessagePacket passwordMessagePacket = new PostgreSQLPasswordMessagePacket(payload);
         PostgreSQLLoginResult loginResult = PostgreSQLAuthenticationHandler.loginWithMd5Password(currentAuthResult.getUsername(), currentAuthResult.getDatabase(), md5Salt, passwordMessagePacket);
         if (PostgreSQLErrorCode.SUCCESSFUL_COMPLETION != loginResult.getErrorCode()) {
-            PostgreSQLErrorResponsePacket responsePacket = createErrorPacket(loginResult.getErrorCode(), loginResult.getErrorMessage());
-            context.writeAndFlush(responsePacket);
-            context.close();
-            return AuthenticationResultBuilder.continued();
-        } else {
-            // TODO implement PostgreSQLServerInfo like MySQLServerInfo
-            context.write(new PostgreSQLAuthenticationOKPacket(true));
-            context.write(new PostgreSQLParameterStatusPacket("server_version", "12.3"));
-            context.write(new PostgreSQLParameterStatusPacket("client_encoding", "UTF8"));
-            context.write(new PostgreSQLParameterStatusPacket("server_encoding", "UTF8"));
-            context.writeAndFlush(new PostgreSQLReadyForQueryPacket());
-            return AuthenticationResultBuilder.finished(currentAuthResult.getUsername(), "", currentAuthResult.getDatabase());
+            throw new PostgreSQLAuthenticationException(loginResult.getErrorCode(), loginResult.getErrorMessage());
         }
-    }
-    
-    private PostgreSQLErrorResponsePacket createErrorPacket(final PostgreSQLErrorCode errorCode, final String errorMessage) {
-        String message = Strings.isNullOrEmpty(errorMessage) ? errorCode.getConditionName() : errorMessage;
-        PostgreSQLErrorResponsePacket packet = PostgreSQLErrorResponsePacket.newBuilder("FATAL", errorCode.getErrorCode(), message).build();
-        return PostgreSQLErrPacketFactory.newInstance(new PSQLException(new ServerErrorMessage(packet.toServerErrorMessage())));
+        // TODO implement PostgreSQLServerInfo like MySQLServerInfo
+        context.write(new PostgreSQLAuthenticationOKPacket(true));
+        context.write(new PostgreSQLParameterStatusPacket("server_version", "12.3"));
+        context.write(new PostgreSQLParameterStatusPacket("client_encoding", "UTF8"));
+        context.write(new PostgreSQLParameterStatusPacket("server_encoding", "UTF8"));
+        context.writeAndFlush(new PostgreSQLReadyForQueryPacket());
+        return AuthenticationResultBuilder.finished(currentAuthResult.getUsername(), "", currentAuthResult.getDatabase());
     }
 }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
index f73d7e8..bb3be67 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.proxy.frontend.postgresql.authentication;
 
+import com.google.common.base.Strings;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.commons.codec.binary.Hex;
@@ -56,7 +57,7 @@ public final class PostgreSQLAuthenticationHandler {
         }
         String md5Digest = passwordMessagePacket.getMd5Digest();
         String expectedMd5Digest = md5Encode(username, user.get().getPassword(), md5Salt);
-        if (!expectedMd5Digest.equals(md5Digest)) {
+        if (!expectedMd5Digest.equals(md5Digest) || !Strings.isNullOrEmpty(databaseName) && !ProxyContext.getInstance().schemaExists(databaseName)) {
             return new PostgreSQLLoginResult(PostgreSQLErrorCode.INVALID_PASSWORD, String.format("password authentication failed for user \"%s\"", username));
         }
         return null == databaseName || SQLCheckEngine.check(databaseName, getRules(databaseName), user.get().getGrantee())
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/InvalidAuthorizationSpecificationException.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/InvalidAuthorizationSpecificationException.java
new file mode 100644
index 0000000..33343e7
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/InvalidAuthorizationSpecificationException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.proxy.frontend.exception.FrontendException;
+
+/**
+ * Invalid authorization specification exception.
+ */
+@Getter
+@RequiredArgsConstructor
+public final class InvalidAuthorizationSpecificationException extends FrontendException {
+    
+    private static final long serialVersionUID = -7169979989631579431L;
+    
+    private final String message;
+}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLAuthenticationException.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLAuthenticationException.java
new file mode 100644
index 0000000..e0024e6
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLAuthenticationException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLErrorCode;
+import org.apache.shardingsphere.proxy.frontend.exception.FrontendException;
+
+/**
+ * PostgreSQL authentication exception.
+ */
+@Getter
+@RequiredArgsConstructor
+public final class PostgreSQLAuthenticationException extends FrontendException {
+    
+    private static final long serialVersionUID = 1331782847269278560L;
+    
+    private final PostgreSQLErrorCode errorCode;
+    
+    private final String message;
+}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLProtocolViolationException.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLProtocolViolationException.java
new file mode 100644
index 0000000..87db44d
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLProtocolViolationException.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.proxy.frontend.exception.FrontendException;
+
+/**
+ * PostgreSQL protocol violation exception.
+ */
+@Getter
+@RequiredArgsConstructor
+public final class PostgreSQLProtocolViolationException extends FrontendException {
+    
+    private static final long serialVersionUID = 6784109729740919997L;
+    
+    private final String expectedMessageType;
+    
+    private final String actualMessageType;
+}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/err/PostgreSQLErrPacketFactory.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/err/PostgreSQLErrPacketFactory.java
index 2712273..e1a3392 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/err/PostgreSQLErrPacketFactory.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/err/PostgreSQLErrPacketFactory.java
@@ -21,7 +21,11 @@ import com.google.common.base.Strings;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLErrorCode;
+import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLMessageSeverityLevel;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.generic.PostgreSQLErrorResponsePacket;
+import org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.InvalidAuthorizationSpecificationException;
+import org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLAuthenticationException;
+import org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLProtocolViolationException;
 import org.postgresql.util.PSQLException;
 import org.postgresql.util.ServerErrorMessage;
 
@@ -44,9 +48,23 @@ public final class PostgreSQLErrPacketFactory {
             return createErrorResponsePacket(((PSQLException) cause).getServerErrorMessage());
         }
         if (cause instanceof SQLException) {
-            return createErrorResponsePacket((SQLException) cause);
+            // TODO consider what severity to use
+            return PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.ERROR.name(), ((SQLException) cause).getSQLState(), cause.getMessage()).build();
         }
-        return createErrorResponsePacket(cause);
+        if (cause instanceof InvalidAuthorizationSpecificationException) {
+            return PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.FATAL.name(), PostgreSQLErrorCode.INVALID_AUTHORIZATION_SPECIFICATION.getErrorCode(), cause.getMessage())
+                    .severityNonLocalized(PostgreSQLMessageSeverityLevel.FATAL.name()).build();
+        }
+        if (cause instanceof PostgreSQLProtocolViolationException) {
+            return PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.FATAL.name(), PostgreSQLErrorCode.PROTOCOL_VIOLATION.getErrorCode(),
+                    String.format("expected %s response, got message type %s", ((PostgreSQLProtocolViolationException) cause).getExpectedMessageType(),
+                            ((PostgreSQLProtocolViolationException) cause).getActualMessageType())).severityNonLocalized(PostgreSQLMessageSeverityLevel.FATAL.name()).build();
+        }
+        if (cause instanceof PostgreSQLAuthenticationException) {
+            return PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.FATAL.name(), ((PostgreSQLAuthenticationException) cause).getErrorCode().getErrorCode(), cause.getMessage())
+                    .build();
+        }
+        return createErrorResponsePacketForUnknownException(cause);
     }
     
     private static PostgreSQLErrorResponsePacket createErrorResponsePacket(final ServerErrorMessage serverErrorMessage) {
@@ -57,14 +75,9 @@ public final class PostgreSQLErrPacketFactory {
                 .constraintName(serverErrorMessage.getConstraint()).file(serverErrorMessage.getFile()).line(serverErrorMessage.getLine()).routine(serverErrorMessage.getRoutine()).build();
     }
     
-    private static PostgreSQLErrorResponsePacket createErrorResponsePacket(final SQLException cause) {
-        // TODO consider what severity to use
-        return PostgreSQLErrorResponsePacket.newBuilder("ERROR", cause.getSQLState(), cause.getMessage()).build();
-    }
-    
-    private static PostgreSQLErrorResponsePacket createErrorResponsePacket(final Exception cause) {
+    private static PostgreSQLErrorResponsePacket createErrorResponsePacketForUnknownException(final Exception cause) {
         // TODO add FIELD_TYPE_CODE for common error and consider what severity to use
         String message = Strings.isNullOrEmpty(cause.getLocalizedMessage()) ? cause.toString() : cause.getLocalizedMessage();
-        return PostgreSQLErrorResponsePacket.newBuilder("ERROR", PostgreSQLErrorCode.SYSTEM_ERROR.getErrorCode(), message).build();
+        return PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.ERROR.name(), PostgreSQLErrorCode.SYSTEM_ERROR.getErrorCode(), message).build();
     }
 }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
index 85db4a5..71255d9 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
@@ -30,6 +30,8 @@ import org.apache.shardingsphere.infra.context.metadata.impl.StandardMetaDataCon
 import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationResult;
+import org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.InvalidAuthorizationSpecificationException;
+import org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLAuthenticationException;
 import org.apache.shardingsphere.transaction.context.TransactionContexts;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -82,13 +84,12 @@ public final class PostgreSQLAuthenticationEngineTest {
         assertThat(actual.isFinished(), is(false));
     }
     
-    @Test
+    @Test(expected = InvalidAuthorizationSpecificationException.class)
     public void assertUserNotSet() {
         PostgreSQLPacketPayload payload = new PostgreSQLPacketPayload(createByteBuf(8, 512));
         payload.writeInt4(64);
         payload.writeInt4(196608);
-        AuthenticationResult actual = new PostgreSQLAuthenticationEngine().authenticate(mock(ChannelHandlerContext.class), payload);
-        assertThat(actual.isFinished(), is(false));
+        new PostgreSQLAuthenticationEngine().authenticate(mock(ChannelHandlerContext.class), payload);
     }
     
     @Test
@@ -96,7 +97,7 @@ public final class PostgreSQLAuthenticationEngineTest {
         assertLogin(password);
     }
     
-    @Test
+    @Test(expected = PostgreSQLAuthenticationException.class)
     public void assertLoginFailed() {
         assertLogin("wrong" + password);
     }