Uzyskiwanie DataSource
wdrożenie
Zwykle sterownik JDBC
zapewnia implementację javax.sql.DataSource
.
Aby uzyskać więcej informacji, zobacz moja odpowiedź na podobne pytanie.
PGSimpleDataSource
Jeśli używasz sterownika JDBC z jdbc.postgresql.org
, możesz użyć org.postgresql.ds.PGSimpleDataSource
klasę jako Twoje DataSource
wdrożenie.
Utwórz wystąpienie obiektu typu PGSimpleDataSource
, a następnie wywołaj metody ustawiające, aby podać wszystkie informacje potrzebne do połączenia z serwerem bazy danych. Strona internetowa w witrynie DigitalOcean zawiera wszystkie te informacje dotyczące konkretnej instancji bazy danych.
Zasadniczo to:
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" );
Wiele nazw serwerów i numerów portów
Niestety pojedyncza wersja metod setServerName
i setPortNumber
są przestarzałe. Chociaż irytujące, powinniśmy prawdopodobnie użyć liczby mnogiej tych metod (setServerNames
&setPortNumbers
), z których każdy pobiera tablicę. Wypełniamy parę jednoelementowych tablic, String[]
i int[]
, z adresem naszego serwera i numerem portu
za pomocą literałów tablicowych:
- { "tutaj jest adres-twojego-serwera" }
- { Twój-numer-portu jest-tu-tutaj}
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" );
Szyfrowanie SSL/TLS
Na koniec musimy dodać informacje dotyczące szyfrowania SSL/TLS, o którym mowa w pytaniu.
Jak na ironię, nie wywołaj setSsl( true )
Można by pomyśleć, że nazwalibyśmy setSsl
metody i przekazać true
. Ale nie. Chociaż jest to sprzeczne z intuicją, ustawienie tego na true spowoduje niepowodzenie prób połączenia. Nie wiem, dlaczego tak jest. Jednak próby i błędy doprowadziły mnie do uniknięcia tego połączenia.
Certyfikat CA
Aby aplikacja Java po stronie klienta mogła zainicjować połączenie SSL/TLS, sterownik JDBC musi mieć dostęp do certyfikatu CA używany przez Ocean Cyfrowy. Na stronie administratora Digital Ocean kliknij Download CA certificate
link do pobrania małego pliku tekstowego. Ten plik będzie miał nazwę ca-certificate.crt
.
Musimy przesłać tekst tego pliku do naszego sterownika JDBC jako ciąg. Wykonaj następujące czynności, aby załadować plik do ciągu tekstowego.
// 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." ); }
Przekaż tekst certyfikatu CA do sterownika JDBC za pomocą wywołania DataSource::setSslCert
. Zauważ, że nie nas wywołanie setSslRootCert
. Nie mieszaj dwóch podobnie nazwanych metod.
dataSource.setSslCert( cert );
Testowanie połączenia
Na koniec możemy użyć skonfigurowanego DataSource
obiekt, aby nawiązać połączenie z bazą danych. Ten kod będzie wyglądał tak:
// Test connection
try (
Connection conn = dataSource.getConnection() ;
// …
)
{
System.out.println( "DEBUG - Postgres connection made. " + Instant.now() );
// …
}
catch ( SQLException e )
{
e.printStackTrace();
}
Pełny przykładowy kod
Łącząc to wszystko razem, zobacz coś takiego.
// 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();
}
Zaufane źródło
Podczas tworzenia instancji Postgres na DigitalOcean.com będziesz mieć możliwość ograniczenia przychodzących żądań połączeń. Możesz określić pojedynczy adres IP, którego oczekuje serwer Postgres, „zaufane źródło” w żargonie Digital Ocean. Hakerzy próbujący połączyć się z Twoim serwerem Postgres będą ignorowani, ponieważ pochodzą z innych adresów IP.
Wskazówka:Kliknij wewnątrz pola wprowadzania danych dla tego numeru adresu IP, aby strona internetowa automatycznie wykryła i zaoferowała adres IP aktualnie używany przez przeglądarkę internetową. Jeśli uruchamiasz kod Java z tego samego komputera, użyj tego samego numeru IP, co w jednym zaufanym źródle.
W przeciwnym razie wpisz adres IP komputera, na którym działa kod Java JDBC.
Inne problemy
Nie zajmowałem się omówieniami, takimi jak odpowiednie protokoły bezpieczeństwa używane do zarządzania plikiem certyfikatu CA lub takie jak udostępnianie informacji o połączeniu przez uzyskanie DataSource
obiekt z JNDI
serwer zamiast hard-coding
. Ale mam nadzieję, że powyższe przykłady pomogą Ci zacząć.