Azure spring boot JPA - spring

Am using azure keyvault to store my db username , url & password. I am using
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-keyvault-secrets</artifactId>
</dependency>
this dependency to read the values configured in keyvaults in my spring boot application. But am getting Failed to determine suitable jdbc url error when the application loads. Can anyone help me one this

nested exception is java.lang.RuntimeException: Driver com.microsoft.sqlserver.jdbc.SQLServerDriver claims to not accept jdbcUrl, ${spring-datasource-url}
There could be a possibility that you might have given wrong MS SQL URL, that might be causing to throw the above exception.
you can refer to the GITHUB documentation which I have followed.
I have tried the same from my end and got expected results:
Step 1:
Open the Azure Cloud Shell and run below command to get list of subscriptions
az account list
Step 2:
Setting the perticular Subscription
az account set -s your\_subscription\_id
Step 3 :
Creating service principal
az ad sp create-for-rbac --name myapp --role Contributor --scopes /subscriptions/mySubscriptionID
Go to Active Directory and select service principal app and store below details:
Your Client_ID
Your Client\_Secret\_Value
Your Tenant_ID
Step 4 :
Follow Below Steps:
Create Resource Group in Azure Portal
Create KeyVault in Azure Portal by selecting resource group
After Creating Key Vault create secret and store your secret key
Now select your key vault and in left hand side select option called “Access policies”.
Click on Create and select the permissions which you want such as “Get, List, Recover, Set, Delete, Backup, Restore” in secret permissions.
Click “Next” and select your service principal app you created in “Step3” and click “Create”.
Step 5:
Now Copy Your Client_ID, Your Client_Secret_Value, Your Tenant_ID and Key Vault URL in Spring Boot application Under resources folder in application.properties file like below:
spring.cloud.azure.keyvault.secret.property-sources[0].credential.client-id=Client_ID
spring.cloud.azure.keyvault.secret.property-sources[0].credential.client-secret=Client_Secret
spring.cloud.azure.keyvault.secret.property-sources[0].endpoint=KeyVault_URL
spring.cloud.azure.keyvault.secret.property-sources[0].profile.tenant-id=Tenant_ID
Output:

spring-cloud-azure-starter-keyvault-secrets fetches values from the keyvault and makes them available as properties, but you have to use the properties somewhere.
You seem to be missing the basic datasource configuration. Assuming the keyvault contains entries for spring-datasource-url, db-username and db-password, in application.yml (or equivalent) you need somethings like:
spring:
datasource:
url: ${spring-datasource-url}
username: ${db-username}
password: ${db-password}
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
jpa:
database-platform: org.hibernate.dialect.SQLServer2012Dialect

Related

Unable to connect to Azure Synapse DB via JDBC using authentication=ActiveDirectoryPassword

I am running into an issue while trying to connect to Azure Synapse DB using JDBC and authentication=ActiveDirectoryPassword.
I am using Java 8 for development. Below are the pom dependencies I am using:
<dependencies>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.4.0.jre8</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>msal4j</artifactId>
<version>1.11.0</version>
</dependency>
</dependencies>
Here's the code I am using for connecting to Synapse DB:
SQLServerDataSource sqlServerDataSource = new SQLServerDataSource();
sqlServerDataSource.setServerName("someserver.database.windows.net");
sqlServerDataSource.setDatabaseName("somedbname");
sqlServerDataSource.setUser("someuser#some.com");
sqlServerDataSource.setPassword("somepwd");
sqlServerDataSource.setAuthentication("ActiveDirectoryPassword");
sqlServerDataSource.setEncrypt(true);
sqlServerDataSource.setTrustServerCertificate(true);
sqlServerDataSource.setUseBulkCopyForBatchInsert(true);
Connection connection = sqlServerDataSource.getConnection();
Here's the MSFT link I was referring to for the above code:
https://learn.microsoft.com/en-us/sql/connect/jdbc/connecting-using-azure-active-directory-authentication?view=sql-server-ver15#connecting-using-activedirectorypassword-authentication-mode
The issue is, the call to sqlServerDataSource.getConnection() is failing with the below error:
com.microsoft.sqlserver.jdbc.SQLServerException: Failed to authenticate the user someuser#some.com in Active Directory (Authentication=ActiveDirectoryPassword). javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.microsoft.sqlserver.jdbc.SQLServerMSAL4JUtils.getCorrectedException(SQLServerMSAL4JUtils.java:228)
at com.microsoft.sqlserver.jdbc.SQLServerMSAL4JUtils.getSqlFedAuthToken(SQLServerMSAL4JUtils.java:65)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.getFedAuthToken(SQLServerConnection.java:4751)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.onFedAuthInfo(SQLServerConnection.java:4724)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.processFedAuthInfo(SQLServerConnection.java:4680)
at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onFedAuthInfo(tdsparser.java:289)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:125)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:37)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:5560)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:4289)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.access$000(SQLServerConnection.java:88)
at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:4227)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7417)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:3488)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2978)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:2628)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:2471)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1470)
at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnectionInternal(SQLServerDataSource.java:1317)
at com.microsoft.sqlserver.jdbc.SQLServerDataSource.getConnection(SQLServerDataSource.java:100)
I am not sure if I need any other dependencies besides the 2 mentioned above.
If anyone has faced a similar issue and would like to share their solution, it would really help.
Thanks in advance.
As per the error, the problem seems to be with user account or certificate so Please try to use, like this sqlServerDataSource.setTrustServerCertificate(false); in your code and try connecting
And make sure to set the azure ADadmin for your server
In the azure portal>>search for sql servers>>and click on your server and go to active directory admin under the settings>> select Set admin.>> In the Add admin page, search for a user, select the user or group to be an administrator, and then Select>> At the top of the Active Directory admin page, select Save.(The changes will take several minutes)
Other option is like you can use contained user, for this a contained user database must exist and a contained database user representing the specified Azure AD user or one of the groups, the specified Azure AD user belongs to, must exist in the database, and must have the CONNECT permission. For this you need to create a contained user and you need to map the user to azure AD.
Reference Create contained users mapped to Azure AD identities

How can I add oidc client secret on Elasticsearch keystore when it is running in K8S?

I have a self hosted Elasticsearch cluster running in AWS EKS and I'd like to setup oidc authentication. I followed the instruction: https://www.elastic.co/guide/en/cloud/current/ec-secure-clusters-oidc.html#ec-oidc-client-secret
In the client-secret setting, it mentions
You’ll need to add the client secret to the keystore
so I launched the ES cluster with basic authentication and added the secret to keystore by using the command elasticsearch-keystore add xpack.security.authc.realms.oidc.oidc-realm.rp.client_secret.
After that I update the ES yaml file to include the configuration:
xpack:
security:
authc:
realms:
oidc:
oidc-realm-name:
order: 2
rp.client_id: "client-id"
rp.response_type: "code"
rp.redirect_uri: "<KIBANA_ENDPOINT_URL>/api/security/v1/oidc"
op.issuer: "<check with your OpenID Connect Provider>"
op.authorization_endpoint: "<check with your OpenID Connect Provider>"
op.token_endpoint: "<check with your OpenID Connect Provider>"
op.userinfo_endpoint: "<check with your OpenID Connect Provider>"
op.jwkset_path: "<check with your OpenID Connect Provider>"
claims.principal: sub
claims.groups: "http://example.info/claims/groups"
then I run rollout restart to restart the pod but I got below error when launching the Elasticsearch cluster:
java.lang.IllegalStateException: security initialization failed
Likely root cause: SettingsException[The configuration setting [xpack.security.authc.realms.oidc.oidc-realm.rp.client_secret] is required]
it seems that ES doesn't find the secret I added in Keystore.
Then I realise that it lost the keystore when I run rollout restart to apply the oidc configuration. so my question is what is the right way to add the OIDC on Elasticsearch in K8S?
If you're using Helm for your deployment, the best way is to add it in the values of the chart.
You'll need to create a secret in your cluster, that will be added to the keystore by an InitContainer.
More details on the Helm chart README

Cloud Foundry is not picking up Oracle Backing Service

I currently have my database credentials saved as ENV Variables. But I want to change that so the database will be a backing service.
Env Variables
SPRING_DATASOURCE_driverClassName: oracle.jdbc.OracleDriver
//sample url to mask mine
SPRING_DATASOURCE_URL: jdbc:oracle:thin:#//spring.guru.csi0i9rgj9ws.us-east-1.rds.a‌​mazonaws.com:1521/OR‌​C
SPRING_DATASOURCE_USERNAME: UserAdmin
SPRING_DATASOURCE_PASSWORD: p4ssw0rd
SPRING_DATASOURCE_initialize: false
Script above works and have database connection when running on cloud foundry.
_ _ - _ _ - _ _
Here is the script I input in my command prompt, where I create a service and bound it to my application
cf cups OracleTest -p 'username, password, url'
Example Link1
Example Link2
Once I fill out all the credentials, bind my application to the service, and restage my application. I do not receive any database connection.
My Attempt on CF
//for uri I also tried
jdbc:oracle:thin:#//spring.guru.csi0i9rgj9ws.us-east-1.rds.a‌​mazonaws.com:1521/OR‌​C
--Do I need some java configuartions along with this?
I did a quick search. I couldn't find an example where you can set the drivername in the CUPS service. You may try removing it from the CUPS definition.
Here is another way of setting the CUPs service - Pivotal Cloud foundry Access Service from Java App
Give it a try
I removed the unnecessary parameters and used the follow
cf cups OracleDB -p '{"jdbcUrl":"jdbc:oracle:thin:[username]/[password]#//[host]:[port]/[service]"}'
So instead of adding each attribute one by one. I found out that it can accept one of the following.
Oracle
The connector will check for:
uri or uris using the scheme oracle
jdbcUrl field in credentials using the scheme oracle
oracleUri, oracleuri, oracleUrl, or oracleurl fields in credentials
I choose jdbc and added credentials in the url.

Unable to setup user registry with "non-LDAP external registry"

I am not able to setup user registry in RTC's JTS setup.
I selected "non-LDAP external registry" option and tried by giving users as "JAdmin", "Administrator", etc.
On click of next it is giving me error message
TypeError: 'this.currentForm.statusMsgHandler' is null or not an object
and Warning:
You need to be authenticated as a user from LDAP to
import your user and assign licenses.
Ensure the application container settings are configured correctly
for LDAP, restart the server, and log in with a user from the LDAP
directory to continue.
I think even if I am selecting "non-LDAP external registry" it is considering "LDAP" option and trying to connect to LDAP (According to log)
javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr:
DSID-0C0906E8, comment: In order to perform this operation
a successful bind must be completed on the connection., data 0, v1db1 ];
Remaining name: 'ou=people,dc=jazz,dc=net'
Please help out to get over it!
I configured RTC using OpenDJ LDAP.

Websphere 7/Data Sources: ORA-01017: invalid username/password;

I am setting up multiple datasources on WS 7 for JNDI access.
After clicking one of the datasources -> Connection Pool Properties -> Connection Pool Custom Properties, I gave two properties:
Property1 Name: user
value: someuser
Property2 Name: password
value: somepassword
And after save the configuration and get back to that data source, I hit the Test connection button so it give me a nice exception:
java.sql.SQLException: ORA-01017: invalid username/password; logon denied DSRA0010E: SQL State = 72000, Error Code = 1,017
And I do see that exception from JVM log as well. The issue remains even get the server restarted?
What's going wrong then?
Update 1
Forget to mention that I have set JAAS authentication to none but still get the exceptions..
You may try using an 'J2C authentication alias' to define your username/password pair instead of custom properties. You may see the link for J2C Authentication Alias definitions at right hand side of datasource definition screen. After you define you username/password pair as an authentication alias, you shall select that alias for your datasource form the list of aliases.
For reference you may check Configuring a data source using the administrative console (item 10) at infocenter.

Resources