Based on oracle document, I create a wallet
mkstore -wrl /tmp/wl -create
Add a credential
mkstore -wrl /tmp/wl -createCredential localhost:1521/myservice user pass
In my java application, I want to connect to the database via this wallet
public static void main(String... args) throws Exception {
Class.forName("oracle.jdbc.driver.OracleDriver");
System.setProperty("oracle.net.wallet_location", "/tmp/wl");
Connection connection = DriverManager.getConnection("WHAT TO PUT HERE?");
}
But I don't know how to fill the connection string.
I would like NOT to use tnsnames.ora
Thanks
In my experience, use of tnsnames.ora was required when using a wallet for authentication, even for JDBC Thin connections. The connection alias in tnsnames.ora is matched to the connection alias in the wallet to provide the correct credential for a given connection.
That said, the latest documentation seems to say that you can enter a connection string along the lines of myhost:1521/myservice or (DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost-scan)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=myservice))) as the db_connect_string parameter in the wallet. This would presumably negate the need for tnsnames.ora, as long as your connection URL after the "#" matched the db_connect_string in the wallet.
You connection URL then looks something like this:
jdbc:oracle:thin:#myhost:1521/myservice
You can pass wallet related connection properties as part of the connection URL. You can skip using tnsnames.ora.
See JDBC developer's guide for some examples.
Related
I need to connect to an external database to copy data from there to my table. I have a TNS file for this external database, and I am trying to connect using JDBC like this:
try {
conn = DriverManager.getConnection("jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=" +
host +
")(PORT=" +
port +
")))(CONNECT_DATA=(SERVICE_NAME=" +
service +
")))",
user,
password);
...
But when trying to connect, i get the error java.net.UnknownHostException (host is not recognized). I guess the problem is that this is an internal host and I don't have access to it.
How to connect to the database using TNS?
You should not need the full TNS text. The following should suffice
getConnection("jdbc:oracle:thin:myuser/mypass#//"+host+":"+port+"/"+service);
If you have a tnsnames.ora then, you can provide the TNS alias as part of your connection string. Make sure you try to login to the Oracle Database through sqlplus using the connection string present in tnsnames.ora.
// dbname_tnsalias - It is the TNS alias present in tnsnames.ora.
// TNS_ADMIN --> Absolute path where tnsnames.ora is present.
final String DB_URL="jdbc:oracle:thin:#dbname_tnsalias?TNS_ADMIN=/Users/test/";
I am using Maria JDBC driver for creating a connection to Amazon Aurora DB
I wanted to create a secured connection so I read here
To connect to a DB cluster with SSL using the MySQL utility
Download the public key for the Amazon RDS signing certificate from
https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem.
Note that this will download a file named rds-combined-ca-bundle.pem.
First Question: How exactly is it secured - anyone can download this pem file from Amazon AWS?
I did some research How should i connect into Aurora DB with public key
and i found these 2 links First, Second
So my Code is quite Simple:
Class.forName("org.mariadb.jdbc.Driver");
Properties prop = new Properties();
prop.setProperty("javax.net.ssl.trustStore","C:\\temp\\rds-combined-ca-bundle.pem");
prop.setProperty("user",jdbcDetails.username);
prop.setProperty("password",jdbcDetails.getSensitiveData());
java.sql.Connection conne = DriverManager.getConnection(jdbcDetails.connectionString, prop);
try (Statement stmt1 = conne.createStatement()) {
// Execute all but the rest
ResultSet rs = stmt1.executeQuery("Select 98765 from dual limit 2");
while(rs.next()) {
rs.getLong(1);
}
}
conne.close();
Second Question: How is having the public key file relate to Encryption?
The above information doesn't get along with Oracle Java information that says:
If the client wants to authenticate the server, then the client's trust store must contain the server's certificate
Third Question: From what I understand if the client trust the server it doesn't require him to use this file
Forth Question: I was checking the connection creation with Wireshark
both cases with and without this public key file i was able to create a connection and both cases in Wireshark appeared Encrypted
Something that looks like that:
Encrypted Application Data:
eb:62:45:fb:10:50:f7:8c............:b9:0a:52:e7:97:1d:34
Base on this answer I understand about public key usage:
First,
It appears that Amazon AWS Azure documentation is misleading a bit - it is only relevant for connection with specific tool called MySQL utility
An answer for First & Second & third Question:
"Java can definitely establish an SSL connection without a client
validating the certificate chain of the server."
the key exchange is made to ensure that the server that it's connected to is indeed the one it was expecting (i.e non-suspicious server)
This means that it's still the same SSL connection made, but with verifyServerCertificate=false it does not verify that it is the intended server
Answer Forth Question:
Currect, The code is in Java - and passing the SSL parameter make it encrypted.
So using these parameter gives what requires
?trustServerCertificate=true&useSSL=true&requireSSL=true&verifyServerCertificate=false
I'm following the JDBC Developer's Guide and trying to test the JDBC thin driver connection using a short java program.
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
class JDBCVersion
{
public static void main (String args[]) throws SQLException
{
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:hr/hr#localhost:1522:orcl");
Connection conn = ods.getConnection();
// Create Oracle DatabaseMetaData object
DatabaseMetaData meta = conn.getMetaData();
// gets driver info:
System.out.println("JDBC driver version is " + meta.getDriverVersion());
}
} //<host>:<port>:<service>
I've tried every possible <host>:<port>:<service> combination but still get a java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection
I've successfully tested the OCI driver using another program included in the tutorial....but can't get this one to work. My application will be using the thin driver to connect to the database so my frustration level is....climbing.
Any help is appreciated.
Maybe following comments could explain why you need the sevice name instead of the SID in the URL.
the Oracle JDBC FAQ mention that SIDs will be cease to be supported in one of the next few releases of the database
the Oracle JDBC devolopers guide mention Always connect to a service. Never use instance_name or SID because these do not direct to known good instances and SID is deprecated
the Oracle 2 day + Java developer tutorial mention the syntax jdbc:oracle:driver_type:[username/password]#//host_name:port_number:SID which seems to be a mixture of SID and service name URL (following the other documents and your working example)
in contrast the javadoc for OracleDriver mention only the SID syntax
the Oracle FAQ wiki mention both syntax
.
jdbc:oracle:thin:[USER/PASSWORD]#[HOST][:PORT]:SID
jdbc:oracle:thin:[USER/PASSWORD]#//[HOST][:PORT]/SERVICE
I'm able to connect to my container DB (containing my tables, packages, etc.) using the username/password.
Returns:
JDBC driver version is 12.1.0.2.0
Still can't connect to the tutorial "HR" PDB that comes with the oracle 12c install and which the JDBC tutorial uses.
Edit:
Got it to work using the following:
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
class JDBCVersion
{
public static void main (String args[]) throws SQLException
{
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:#//localhost:1522/pdborcl.global.XXXXXXXX.com");
ods.setUser("hr");
ods.setPassword("hr");
Connection conn = ods.getConnection();
// Create Oracle DatabaseMetaData object
DatabaseMetaData meta = conn.getMetaData();
// gets driver info:
System.out.println("JDBC driver version is " + meta.getDriverVersion());
}
}
Still don't understand why I need the full global name instead of the instance name.
When connecting to a PDB you should always use the PDB's service name in the connection string. It looks like your PDB's service is "pdborcl.global.XXXXXXXX.com" so that's what you need to use to connect the PDB directly.
Personally I find it easier to use the long URL format:
"jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=pdborcl.global.XXXXXXXX.com)))"
It makes it obvious that you're using a Service name instead of an SID.
The beauty of it is that you can also easily test your connection string with sqlplus:
sqlplus "hr/hr#(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=pdborcl.global.XXXXXXXX.com)))"
If sqlplus works there is not reason why the JDBC Thin driver wouldn't.
Finally you can also connect the root database using a privilege user and then execute "ALTER SESSION SET CONTAINER=pdb" to switch to the PDB. Should you decide to do so you would have to modify your connection string to connect to the root container first. It should have its own service name.
The connection url which we all use for mySql in java is :-
Connection c = DriverManager.getConnection("jdbc:mysql://localhost/THE_DB", "root", "");
But I want to know that is it possible to use a url like C:\\Documents\\Folder\\THE_DB as the connection URL? If yes, then please tell me what the connection URL would be...
The database URL provided in the getConnection(String url) method should follow the database driver unified network resource syntax:
jdbc: subprotocol: subname
Note that each driver may have its own subprotocol and each subprotocol may have its own syntax for the source.
I already have the connection string and DBA username. I accept DBA password from the user.
To check if the password provided by him is correct, I try to create a connection using
String connString = "jdbc:oracle:thin:#" + connDesc;
Properties props = new Properties();
props.put("user", user);
props.put("password", pwd);
props.put("internal_logon", "sysdba");
Class.forName("oracle.jdbc.OracleDriver").newInstance();
Connection conn = DriverManager.getConnection(connString, props);
Now when it throws SQLException I need to find if that exception is because of wrong password or network timeout. Is there any way to do that?
Also, is there any better way to validate password than what I'm currently doing?
You can use the SQLException.getErrorCode() method to read the Oracle-specific error code for the error.
For an invalid username/password combination, the error code is 1017.
It's not clear to me exactly what error you mean by 'network timeout'. If the message is The Network Adapter could not establish the connection, then the error code you want appears to be 17002. (I got this error attempting to connect to my local Oracle XE instance using JDBC but with the TNS listener shut down.)
There isn't a better way of validating a username/password than attempting to create a connection to the database using that username and password.