Få en DataSource
implementering
Vanligtvis är din JDBC-drivrutin
tillhandahåller en implementering av javax.sql.DataSource
.
För mer information, se mitt svar till en liknande fråga.
PGSimpleDataSource
Om du använder JDBC-drivrutinen från jdbc.postgresql.org
, kan du använda org.postgresql.ds.PGSimpleDataSource
klass som din DataSource
implementering.
Instantiera ett objekt av typen PGSimpleDataSource
, anropa sedan sättermetoder för att tillhandahålla all information som behövs för att ansluta till din databasserver. Webbsidan på DigitalOcean-webbplatsen listar all denna information för just din databasinstans.
I grund och botten detta:
PGSimpleDataSource dataSource = new PGSimpleDataSource();
dataSource.setServerName( "your-server-address-goes-here" );
dataSource.setPortNumber( your-port-number-goes-here );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );
Fler servernamn och portnummer
Tyvärr, den singulära versionen av metoderna setServerName
och setPortNumber
är utfasade. Även om det är irriterande bör vi förmodligen använda pluralversionen av dessa metoder (setServerNames
&setPortNumbers
) som var och en tar en array. Vi fyller i ett par enelementsmatriser, String[]
och int[]
, med vår servers adress och portnummer
använder arrayliterals:
- { "din-server-adress-går-här" }
- { ditt-portnummer-går-här }
PGSimpleDataSource dataSource = new PGSimpleDataSource();
String[] serverAddresses = { "your-server-address-goes-here" };
dataSource.setServerNames( serverAddresses );
int[] serverPortNumbers = { your-port-number-goes-here };
dataSource.setPortNumbers( serverPortNumbers );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );
SSL/TLS-kryptering
Slutligen måste vi lägga till information för SSL/TLS-krypteringen som behandlas i frågan.
Gör ironiskt nog inte anrop setSsl( true )
Du skulle kunna tro att vi skulle kalla setSsl
metod och pass true
. Men nej. Även om det är kontraintuitivt, kommer att ställa in det till sant göra att dina anslutningsförsök misslyckas. Jag vet inte varför det är så. Men försök och misstag fick mig att undvika det samtalet.
CA-certifikat
För att din Java-app på klientsidan ska initiera SSL/TLS-anslutningen måste JDBC-drivrutinen ha tillgång till CA-certifikatet används av Digital Ocean. På din Digital Ocean-administratörssida klickar du på Download CA certificate
länk för att ladda ner en liten textfil. Den filen kommer att heta ca-certificate.crt
.
Vi måste mata in texten i den filen till vår JDBC-drivrutin som en sträng. Gör följande för att ladda filen i en textsträng.
// Get CA certificate used in TLS connections.
Path path = Paths.get( "/Users/basilbourque/Downloads/ca-certificate.crt" );
String cert = null;
try
{
cert = Files.readString( path , StandardCharsets.UTF_8 );
System.out.println( "cert = " + cert );
}
catch ( IOException ex )
{
throw new IllegalStateException( "Unable to load the TLS certificate needed to make database connections." );
}
Objects.requireNonNull( cert );
if ( cert.isEmpty() ) {throw new IllegalStateException( "Failed to load TLS cert." ); }
Skicka CA-certifikattexten till din JDBC-drivrutin med ett anrop till DataSource::setSslCert
. Observera att vi inte är det ringer setSslRootCert
. Blanda inte ihop de två metoderna med samma namn.
dataSource.setSslCert( cert );
Testar anslutningen
Slutligen kan vi använda den konfigurerade DataSource
objekt för att göra en anslutning till databasen. Den koden kommer att se ut så här:
// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}
Fullständig exempelkod
Om du sätter ihop allt det här kan du se något sånt här.
// Get CA certificate used in TLS connections.
Path path = Paths.get( "/Users/basilbourque/Downloads/ca-certificate.crt" );
String cert = null;
try
{
cert = Files.readString( path , StandardCharsets.UTF_8 );
System.out.println( "cert = " + cert );
}
catch ( IOException ex )
{
throw new IllegalStateException( "Unable to load the TLS certificate needed to make database connections." );
}
Objects.requireNonNull( cert );
if ( cert.isEmpty() ) {throw new IllegalStateException( "Failed to load TLS cert." ); }
// PGSimpleDataSource configuration
PGSimpleDataSource dataSource = new PGSimpleDataSource();
String[] serverAddresses = { "your-server-address-goes-here" };
dataSource.setServerNames( serverAddresses );
int[] serverPortNumbers = { your-port-number-goes-here };
dataSource.setPortNumbers( serverPortNumbers );
dataSource.setSslCert( cert );
dataSource.setDatabaseName( "defaultdb" );
dataSource.setUser( "doadmin" );
dataSource.setPassword( "your-password-goes-here" );
// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}
Tillförlitlig källa
När du skapar din Postgres-instans på DigitalOcean.com kommer du att erbjudas möjligheten att begränsa inkommande anslutningsförfrågningar. Du kan ange en enda IP-adress som förväntas av Postgres-servern, en "pålitlig källa" på Digital Oceans språkbruk. Alla hackare som försöker ansluta till din Postgres-server kommer att ignoreras eftersom de kommer från andra IP-adresser.
Tips:Klicka i datainmatningsfältet för detta IP-adressnummer för att få webbsidan att automatiskt upptäcka och erbjuda den IP-adress som för närvarande används av din webbläsare. Om du kör din Java-kod från samma dator, använd samma IP-nummer som din enda betrodda källa.
Annars skriver du in IP-adressen till datorn som kör din Java JDBC-kod.
Andra problem
Jag har inte tagit upp fördjupningar, till exempel korrekta säkerhetsprotokoll att använda för att hantera din CA-certifikatfil, eller som att externisera din anslutningsinformation genom att skaffa en DataSource
objekt från en JNDI
server snarare än hårdkodning
. Men förhoppningsvis hjälper exemplen ovan dig att komma igång.