Anskaffelse af en DataSource
implementering
Normalt er din JDBC-driver
leverer en implementering af javax.sql.DataSource
.
For flere detaljer, se mit svar til et lignende spørgsmål.
PGSimpleDataSource
Hvis du bruger JDBC-driveren fra jdbc.postgresql.org
, kan du bruge org.postgresql.ds.PGSimpleDataSource
klasse som din DataSource
implementering.
Instantiér et objekt af typen PGSimpleDataSource
, og kald derefter setter-metoder for at give alle de nødvendige oplysninger for at oprette forbindelse til din databaseserver. Websiden på DigitalOcean-webstedet viser alle disse oplysninger for netop din databaseforekomst.
Dybest set dette:
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" );
Flertal servernavne og portnumre
Desværre er den ene version af metoderne setServerName
og setPortNumber
er forældede. Selvom det er irriterende, bør vi nok bruge flertalsversionen af disse metoder (setServerNames
&setPortNumbers
), der hver tager et array. Vi udfylder et par enkeltelement-arrays, String[]
og int[]
, med vores servers adresse og portnummer
ved hjælp af array-literals:
- { "din-server-adresse-går-her" }
- { dit-port-nummer-går-her }
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
Til sidst skal vi tilføje info om SSL/TLS-krypteringen, der er adresseret i spørgsmålet.
Ironisk nok ikke kald setSsl( true )
Du skulle tro, vi ville kalde setSsl
metode og pass true
. Men nej. Selvom det er kontraintuitivt, vil det at sætte det til sandt få dine forbindelsesforsøg til at mislykkes. Jeg ved ikke hvorfor det er sådan. Men trial-and-error fik mig til at undgå det opkald.
CA-certifikat
For at din Java-app på klientsiden kan starte SSL/TLS-forbindelsen, skal JDBC-driveren have adgang til CA-certifikatet bruges af Digital Ocean. På din Digital Ocean-administratorside skal du klikke på Download CA certificate
link til at downloade en lille tekstfil. Denne fil vil få navnet ca-certificate.crt
.
Vi skal føre teksten fra den fil til vores JDBC-driver som en streng. Gør følgende for at indlæse filen i en tekststreng.
// 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." ); }
Send denne CA-certifikattekst til din JDBC-driver med et opkald til DataSource::setSslCert
. Bemærk, at vi ikke er kalder setSslRootCert
. Bland ikke de to metoder med samme navn.
dataSource.setSslCert( cert );
Test af forbindelsen
Til sidst kan vi bruge den konfigurerede DataSource
objekt for at oprette forbindelse til databasen. Den kode vil se sådan ud:
// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}
Fuldfør eksempelkode
Hvis du sætter alt det sammen, kan du se noget som dette.
// 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();
}
Pålidelig kilde
Når du opretter din Postgres-instans på DigitalOcean.com, vil du blive tilbudt muligheden for at begrænse indgående forbindelsesanmodninger. Du kan angive en enkelt IP-adresse, der forventes af Postgres-serveren, en "betroet kilde" på Digital Oceans sprog. Alle hackere, der forsøger at oprette forbindelse til din Postgres-server, vil blive ignoreret, da de stammer fra andre IP-adresser.
Tip:Klik inde i dataindtastningsfeltet for dette IP-adressenummer for at få websiden til automatisk at finde og tilbyde den IP-adresse, der i øjeblikket bruges af din webbrowser. Hvis du kører din Java-kode fra den samme computer, skal du bruge det samme IP-nummer som din enkelt betroede kilde.
Ellers skal du indtaste IP-adressen på den computer, der kører din Java JDBC-kode.
Andre problemer
Jeg har ikke behandlet uddybninger, såsom korrekte sikkerhedsprotokoller, der skal bruges til at administrere din CA-certifikatfil, eller såsom eksternalisering af dine forbindelsesoplysninger ved at få en DataSource
objekt fra en JNDI
server i stedet for hard-coding
. Men forhåbentlig hjælper ovenstående eksempler dig i gang.