db-derby-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rick Hillegas <rick.hille...@oracle.com>
Subject Re: User authorisation
Date Fri, 27 Apr 2012 14:12:25 GMT
Hi Trejkaz,

I can reproduce your results if my UserAuthenticator throws a 
SQLException whose SQLState is 08004, one of the SQLStates reserved for 
use by Derby. If my UserAuthenticator throws a SQLException whose 
SQLState is ZZZZZ, a state not reserved by Derby, then the exception 
traverses the network correctly and is seen by the client application. 
Here is a sample program showing the success case:

import java.sql.*;

public class ZZ
{
     public static void main( String... args ) throws Exception
     {
         try {
             Connection  conn = DriverManager.getConnection
                 ( 
"jdbc:derby://localhost:8246/memory:db;create=true;user=foo;password=bar" );
         }
         catch (Throwable t) { printThrowable( t ); }
     }

     private static  void    printThrowable( Throwable t )
     {
         if ( t == null ) { return; }

         println( "\nThrowable is a " + t.getClass().getName() );
         println( "    message = " + t.getMessage() );

         if ( t instanceof SQLException )
         {
             SQLException    se = (SQLException) t;

             println( "    SQLState = " + se.getSQLState() );
             printThrowable( se.getNextException() );
         }

         printThrowable( t.getCause() );
     }

     private static  void    println( String text ) { 
System.out.println( text ); }
}

...and here is the UserAuthenticator I used:

import java.sql.SQLException;
import java.util.Properties;

import org.apache.derby.authentication.UserAuthenticator;

public class Z implements UserAuthenticator
{
     public Z() {}

     public boolean authenticateUser
         (
          String userName,
          String userPassword,
          String databaseName,
          Properties info
          )
        throws SQLException
     {
         throw new SQLException( "I can't do that, Dave.", "ZZZZZ" );
     }
}

Hope this helps,
-Rick

On 4/26/12 10:09 PM, Trejkaz wrote:
> On Mon, Apr 23, 2012 at 10:50 PM, Rick Hillegas
> <rick.hillegas@oracle.com>  wrote:
>> UserAuthenticator.authenticateUser() can throw a SQLException which explains
>> that the user doesn't have access to the given database. I find that
>> SQLExceptions raised by the following code reach the application:
> [snip]
>
> I just gave this a shot, but it doesn't appear to work, at least not
> over the client-server connection.
>
> I tried it using a mock authenticator:
>
>      mockery.checking(new Expectations() {{
>          oneOf(authenticator).authenticateUser("bob", "bob",
> dbDir.getAbsolutePath(), new Properties());
>          will(throwException(new
> SQLNonTransientConnectionException("Database access denied for user
> bob", "08004.C.3")));
>      }});
>
> Then when I connect to the database, I do get back SQLState "08004",
> but it's "08004.C.1" with a different error message to the one I
> returned. My initial guess would be that Derby swallows the
> authentication exception on the server side, sends some kind of error
> code over the wire and then the client driver propagates a brand new
> exception to the application.
>
> TX
>


Mime
View raw message