Updating auto renewed DB password in JDBC connection - Spring Boot - spring-boot

I have a strange use case running spring boot microservices, the services lives inside an openshift cluster and the problem I face is due to a database password renewal policy.
The app uses JDBC connection to access an oracle database and the DB password is retrieved during container startup from a homegrown vault. The issue is the password keeps change once every 90 days.
The application uses JDBC connection pool to talk to the database and the service is expected to receive a high volume of traffic, therefore an increased number of sessions. In the middle of a session if the password gets renewed how do we ensure we use the working password to run queries always in the jdbc connection pool.
We tried a couple of things running a separate service that would retrieve the password momentarily and the consumer service which requires the password would simply use the last successful password from the database service, its kind of an ugly implementation.
Tried multi-container pods with an Auxillary pod listening for database changes and that was a lame idea as well.
The core problem is loading up JDBC connection pool which already has the auth to establish to connection and communicate with the database. So in the middle of a session how do we update the password?
Any ideas ?

I suppose you are using a secret store (e.g.: Vault, AWS Secrets Manager, etc.) to get the password. If so, I think you are halfway done.
Check out #RefreshScope, you can refresh the spring context which will fetch the new configuration (the password) and recreate some beans (the datasource).

Related

Use gMSA for Hashicorp Vault mssql credential rotation

I want to start using Vault to rotate credentials for mssql databases, and I need to be able to use a gMSA in my mssql connection string. My organization currently only uses Windows servers and will only provide gMSAs for service accounts.
Specifying the gMSA as the user id in the connection string returns the 400 error error creating database object: error verifying connection: InitialBytes InitializeSecurityContext failed 8009030c.
I also tried transitioning my vault services to use the gMSA as their log on user, but this made nodes unable to become a leader node even though they were able to join the cluster and forward requests.
My setup:
I have a Vault cluster running across a few Windows servers. I use nssm to run them as a Windows service since there is no native Windows service support.
nssm is configured to run vault server -config="C:\vault\config.hcl" and uses the Local System account to run under.
When I change the user, the node is able to start up and join the raft cluster as a follower, but can not obtain leader status, which causes my cluster to become unresponsive once the Local System user nodes are off.
The servers are running on Windows Server 2022 and Vault is at v1.10.3, using integrated raft storage. I have 5 vault nodes in my cluster.
I tried running the following command to configure my database secret engine:
vault write database/config/testdb \
connection_url='server=myserver\testdb;user id=domain\gmsaUser;database=mydb;app name=vault;' \
allowed_roles="my-role"
which caused the error message I mentioned above.
I then tried to change the log on user for the service. I followed these steps to rotate the user:
Updated the directory permissions for everywhere vault is touching (configs, certificates, storage) to include my gMSA user. I gave it read permissions for the config and certificate files and read/write for storage.
Stopped the service
Removed the node as a peer from the cluster using vault operator raft remove-peer instanceName.
Deleted the old storage files
Changed the service user by running sc.exe --% config "vault" obj="domain\gmsaUser" type= own.
Started the service back up and waited for replication
When I completed the last step, I could see the node reappear as a voter in the Vault UI. I was able to directly hit the node using the cli and ui and get a response. This is not an enterprise cluster, so this should have just forwarded the request to the leader, confirming that the clustering portion was working.
Before I got to the last node, I tried running vault operator step-down and was never able to get the leader to rotate. Turning off the last node made the cluster unresponsive.
I did not expect changing the log on user to cause any issue with node's ability to operate. I reviewed the logs but there was nothing out of the ordinary, even by setting the log level to trace. They do show successful unseal, standby mode, and joining the raft cluster.
Most of the documentation I have found for the mssql secret engine includes creating a user/pass at the sql server for Vault to use, which is not an option for me. Is there any way I can use the gMSA in my mssql config?
When you put user id into the SQL connection string it will try to do SQL authentication and no longer try windows authentication (while gMSA is a windows authentication based).
When setting up the gMSA account did you specify the correct parameter for who is allowed to retrieve the password (correct: PrincipalsAllowedToRetrieveManagedPassword, incorrect but first suggestion when using tab completion PrincipalsAllowedToDelegateToAccount)
maybe you need to Install-ADServiceAccount ... on the machine you're running vault on

What is the best way to store database username and password in microservice

While developing microservice (for e.g. spring boot service), we are storing database username and password in properties file. Microservice would connect to database using these database credentials.
Is there any other best way to store database username and password ?
What are best techniques to store database user and password securely in encrypted format and how to decrypt before connecting to database schema?
We are using Chef Cookbook (DevOps), Chef Client for deployment of microservices in Amazon Web Services(AWS)
One possible solution is to have a Config Server to which your applications connect and get their configurations at startup time. This Config Server might decrypt the encrypted sensitive data.
A simple example: https://spring.io/guides/gs/centralized-configuration/

session management in server application

i am developing a server application of building rest web services in java using spring-hibernate,where this service will be used by other clients.i have followed this link http://www.beingjavaguys.com/2014/08/spring-restful-web-services.html.
my question here is
1>should i maintain session in server application?if yes how?
2>should i do any validation in server side?
3>To validate user while login should i use spring security for that or just comparing username and password in database is enough?
4>when user doesnot interact with server for particular time there should be session timeout ,should this be implemented in sserver application or client side?
i am very new to java and web service,any suggestions,links and guidence are appreciated.
1>should i maintain session in server application?if yes how?
Rest web services do not depend on client session since they are stateless, so there is no need to think about session management.
2>should i do any validation in server side?
What kind of validation?
3>To validate user while login should i use spring security for that or just comparing username and password in database is enough?
You can use both, but I think a token based authentication (Based on spring security) will be the best way.
4>when user does not interact with server for particular time there should be session timeout ,should this be implemented in server application or client side?
Since server does not keep track of user session, timeout should be implemented on client side.
You can check the following project if you want its a excellent starting point.
https://github.com/dhavaln/spring-rest-boilerplate
1>should i maintain session in server application?if yes how?
Web-services are stateless means server does not store any state about the client session on the server side.You should manage the session on the client side, other wise you will end-up handling an heavy load of sessions on the server side and I am sure you don't want to do that.
2>should i do any validation in server side?
If by validation you mean data integrity, I think you will have to do it for the favor of data integrity and your application well being.
3>To validate user while login should i use spring security for that
or just comparing username and password in database is enough?
You can do both, using spring security is a good choice , and you will have to configure or build your own AuthentificationManager which will compare credentials withe those stored in the database
4>when user doesnot interact with server for particular time there
should be session timeout ,should this be implemented in sserver
application or client side?
You can set a session timeout , and this should be implemented on the client-side.

WebSphere to Oracle - doesn't accept correct password

In WebSphere 6.1 I have created a datasource to an Oracle 11g instance using the thin JDBC client.
In Oracle I have two users, one existing and another newly created.
My websphere datasource is OK if I use the component-managed authentication alias of the existing user, but fails with "invalid user/password" message if I use the alias of the new user. The error message is:
The test connection operation failed for data source MyDB (Non-XA) on
server nodeagent at node MY_node with the following exception:
java.sql.SQLException: ORA-01017: invalid username/password;
logon denied DSRA0010E: SQL State = 72000, Error Code = 1,017.
View JVM logs for further details.
There is nothing in the JVM logs. I have grepped all websphere logs and they do not mention my connection at all.
I can confirm that the username and password are correct by logging in via SQLPlus or (to prove the JDBC connection is OK) via SQuirreL.
I have checked in Oracle that the new user has all the system privs that the existing user has.
Any thoughts on what is going on or how I can debug this further?
Just FYI. I am guessing you are running WebSphere in Network Deployment mode.
This behavior you're experiencing is actually by design.
The reason for it is that the "Test Connection" button you see on the admin console, invokes the JDBC connection test from within the process of the Node Agent. There is no way for the J2C Alias information to propagate to the Node Agent without restarting it; some configuration objects take effect in WebSphere as soon as you save the configuration to the master repository, and some only take effect on a restart. J2C aliases take effect on restarts.
In a Network Deployment topology, you may have any number of server instances controlled by the same Node Agent. You may restart your server instances as you'd like, but unless you restart the Node Agent itself, the "test connection" button will never work.
It's a known WebSphere limitation... Which also exists on version 7.0, so don't be surprised when you test it during your next migration. :-)
If this happens to anyone else, I restarted WebSphere and all my problems went away. It's a true hallmark of quality software.
Oftentimes when people tell me they can't log into Oracle 11g with the correct password, I know they've been caught out by passwords becoming case-sensitive between 10g and 11g.
Try this :
data source definition
security
use the j2c alias both autentication managed by component and autentication managed by container
IBM WAS 8.5.5 Knowledge Center - Managing Java 2 Connector Architecture authentication data entries for JAAS
If you create or update a data source that points to a newly created J2C authentication data alias, the test connection fails to connect until you restart the deployment manager.
After you restart the deployment manager, the J2C authentication data is reflected in the runtime configuration. Any changes to the J2C authentication data fields require a deployment manager restart for the changes to take effect.
The node agent must also be restarted.
I have point my data source to componenet-manage authentication as well as container-managed authentication.Its working fine now........

Logging into oracle db as a global user

We are trying to shape up an old, 2 tier, Delphi based application. It originally uses database authentication, we'd like to transform the db user accounts to global users, so an OID server could perform the authentication instead of the database.
The Delphi program can no longer log into the database if the account is a global user. I'm trying to understand the login protocol, so far without results.
Similar thing happens with SQLDeveloper, I can't connect as a global user. SQLPlus however works with both kinds of users. We checked the information flow with Wireshark. When the dbserver asks back for a password, the SQLPlus sends it, while the SQLDeveloper doesn't send a password when attempting to connect as a global user.
The client sends the application name too in the login request. Is it possible that we have to store the client app name in the LDAP itself?
To connect to Oracle using OID, application must properly configure OCI (Oracle Call Interface). The data access components (which one ?), you are using, must set OCI_ATTR_DISTINGUISHED_NAME session attribute. If that is not done, then you will be not able to connect to Oracle server using ODI and OCI.
You should check your components documentation for this feature. And if it is not implemented, then discuss this issue with the components vendor. Actually, there is not much work to implement, but some work to setup testing environment is required ...

Resources