Een DataSource
verkrijgen implementatie
Gewoonlijk uw JDBC-stuurprogramma
biedt een implementatie van javax.sql.DataSource
.
Zie mijn antwoord voor meer informatie. op een soortgelijke vraag.
PGSimpleDataSource
Bij gebruik van het JDBC-stuurprogramma van jdbc.postgresql.org
, kunt u de org.postgresql.ds.PGSimpleDataSource
class als uw DataSource
implementatie.
Instantieer een object van het type PGSimpleDataSource
en roep vervolgens setter-methoden aan om alle informatie te verstrekken die nodig is om verbinding te maken met uw databaseserver. De webpagina op de DigitalOcean-site vermeldt al deze stukjes informatie voor uw specifieke database-instantie.
Eigenlijk dit:
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" );
Meervoudige servernamen en poortnummers
Helaas is de enkelvoudige versie van de methoden setServerName
en setPortNumber
zijn afgekeurd. Hoewel vervelend, zouden we waarschijnlijk de meervoudsversie van die methoden moeten gebruiken (setServerNames
&setPortNumbers
) die elk een array nemen. We vullen een paar arrays met één element, String[]
en int[]
, met het adres van onze server en poortnummer
arrayletters gebruiken:
- { "uw-server-adres-gaat-hier" }
- { uw-poort-nummer-gaat-hier }
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-codering
Ten slotte moeten we informatie toevoegen voor de SSL/TLS-codering die in de vraag wordt behandeld.
Ironisch genoeg, niet bel setSsl( true )
Je zou denken dat we de setSsl
methode en geef true
door . Maar nee. Hoewel het contra-intuïtief is, zal het instellen van dat op waar ertoe leiden dat uw verbindingspogingen mislukken. Ik weet niet waarom dat is. Maar door vallen en opstaan moest ik die oproep vermijden.
CA-certificaat
Om uw client-side Java-app de SSL/TLS-verbinding te laten starten, moet het JDBC-stuurprogramma toegang hebben tot het CA-certificaat gebruikt door Digital Ocean. Klik op uw Digital Ocean-beheerpagina op Download CA certificate
link om een klein tekstbestand te downloaden. Dat bestand krijgt de naam ca-certificate.crt
.
We moeten de tekst van dat bestand als een string naar ons JDBC-stuurprogramma voeren. Doe het volgende om het bestand in een tekenreeks te laden.
// 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." ); }
Geef die CA-certificaattekst door aan uw JDBC-stuurprogramma met een oproep naar DataSource::setSslCert
. Merk op dat we niet . zijn aanroepen van setSslRootCert
. Haal de twee gelijknamige methoden niet door elkaar.
dataSource.setSslCert( cert );
De verbinding testen
Ten slotte kunnen we de geconfigureerde DataSource
. gebruiken object om verbinding te maken met de database. Die code ziet er als volgt uit:
// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}
Volledige voorbeeldcode
Als je dat allemaal samenvoegt, zie je zoiets als dit.
// 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();
}
Vertrouwde bron
Wanneer u uw Postgres-instantie op DigitalOcean.com maakt, krijgt u de mogelijkheid om inkomende verbindingsverzoeken te beperken. U kunt een enkel IP-adres specificeren dat door de Postgres-server wordt verwacht, een "vertrouwde bron" in het jargon van Digital Ocean. Hackers die proberen verbinding te maken met uw Postgres-server worden genegeerd omdat ze afkomstig zijn van andere IP-adressen.
Tip:Klik in het gegevensinvoerveld voor dit IP-adresnummer om de webpagina automatisch het IP-adres te laten detecteren en aanbieden dat momenteel door uw webbrowser wordt gebruikt. Als u uw Java-code vanaf dezelfde computer uitvoert, gebruik dan hetzelfde IP-nummer als uw enige vertrouwde bron.
Typ anders het IP-adres van de computer waarop uw Java JDBC-code draait.
Andere problemen
Ik ben niet ingegaan op de uitwerkingen, zoals de juiste beveiligingsprotocollen die moeten worden gebruikt om uw CA-certificaatbestand te beheren, of zoals het externaliseren van uw verbindingsinformatie door een DataSource
te verkrijgen object van een JNDI
server in plaats van hard-coding
. Maar hopelijk helpen de bovenstaande voorbeelden je op weg.