Make sure JDBC/JPA won't modify the DB? - sql-server

I have a MS SQL Server with a DB that is constantly updated.
I have the credentials to access it with admin privileges.
And I'm making a Java EE webapp to display (hence, only display) its data.
But I have to make sure that, under any consequences,
My webapp doesn't modify the DB.
And no, the owners of the DB don't want to make an unprivileged user for the webapp.
Any ideas? I'm using JDBC + JPA.

In EclipseLink you could mark all your objects as #ReadOnly, so they won't be written.
You could also register an event listener to throw an error on persist, update or remove.

Related

Per user database authentication in Django

Good afternoon,
I am writing a front-end for a research database that holds sensitive health information. My institution has a policy that user actions be logged by the SQL server so that they can perform audits on the server log files in the event of a breach.
Because of this policy, I cannot connect Django to the db as a system user (otherwise, all users of the front-end actions would be logged by the server as the Django system user instead as the actual user individually).
Is there a way to connect to the DB using per user credentials so that actions performed on the front end will be logged as that user on the db server? I have been able to find a lot of information about using multiple databases, but nothing about per user authentication of those databases.
Thank you in advanced!
I don't think you can do that, the user that connect to the database need to have access to all the tables.
I had a similar issue when I wanted to use Django models outside Django and restrict access to certain models for certain users.
I ended up using SQLAlchemy and its automap feature on the existing Django database. Then you can connect to the database using your SQL users.
However, if you don't mind all the users accessing all the tables and are only concerned about the logs, maybe you can use a different settings.py or at least a different DATABASES configuration for each user?
I was able to accomplish this by giving the SQL user the IMPERSONATE permission and performing EXECUTE AS prior to the DB queries that I needed to have logged in models.py.
cursor = self.connection.cursor()
try:
cursor.execute("EXECUTE AS " + get_current_user()
except DatabaseError as e:
cursor.close()
raise e

How do I configure database connection per user account in Spring Data?

We have a requirement that user account can provide username/password for database. This means that after user account is loaded, the user should use his own database connection for persistence.
How do I configure that in Spring Data?
Which database?
Which ORM implementation?
Spring has the AbstractRoutingDataSource, which lets you change the DataSource at runtime.
You could also use a delegation pattern, where the web server connects as a limited user, and then changes role to a different user if their authentication is successful. See How to run SQL SET statements against db at start of connection/session using Hibernate? and Switch role after connecting to database
You'll probably need to disable caching in your ORM too.

Settings per connected user

I have an windows forms application which I'm migrating from MySql to MsSql. In MySql we are using database users for every user. So every user connects to the database using their own account. This is not what we want, because in the future we want the application set open to the world and database users is not a thing on the wishlist. So this is going away.
The problem is that many views work with a function which uses CURRENT_USER() to give access to records (because users are part of a department and are not allowed to see all records of all departments).
In MsSql we are using just one type of connectionstring, but every application connects the database directly. Is it possible in MSSQL to store variables per connection so I can identify a user in the view by the variable I set after creating the connection?
So it would be like this:
Start application
Users logs on
Application creates connection with mssql
Application sets a variables on sql-server
User opens a screen with a view
SQL server returns the view using the variable that has ben set earlier to only return the allowed records to view.
So every user must have it's own variable. Is that possible?
Application is build with NET and iBatis. Not the best combination, but iBatis is to much integrated to throw it all overboard.
While this may or may not be possible, it's definitely not the right way to go. As you said, you're using a single connection string, and likely using a pool of connections to access the database. As you want users to be able to pick any available connection in the pool to do their queries, you don't want any user state (or any state at all for that matter) to be tied to the connection.
As you're opening up to the world, you don't want the application to directly connect to the database. Instead, you should implement middleware that will handle authentication and access rights, and only return data from the database that the user may access. So instead of
user application <- iBatis -> MSSQL
you'll have:
user application <- HTTP/something else -> API <- iBatis -> MSSQL
This is the approach taken used by websites as well. In addition, you'll be able to add functionality like caching, connection pooling etc. to the API, making it possible to support more users.

database access impersonation

My objective is to prevent direct user access to the database server. One way is to create a WCF service or web service in the middle between the front end application and the database server.
First of all, the users will be authenticated to the application. Subsequently the application will connect through the WCF service to perform business logic operations. The WCF service will perform the database related operations by using one windows account. This will prevent other users to directly access the database server, since the permission will only be granted to specific one windows account.
Here are my questions : Even though the database access is only granted to one windows account and the WCF will use this windows account to perform database related operations, is it possible to mark all database related operations with the credential of the logged in user ?
Update
Thanks for the replies. Seems like the above scenario is not achievable. I am currently exploring the SQL 2008 Application Role feature. One of the example is here. But after further exploration, apparently there is an issue with the connection pooling.
Update
There is a stack overflow thread here regarding SQL Server Application Role
You'd have to have every user set up in sys.server_principals to enable context switching like EXECUTE AS which would mean that they have direct db access anyway.
If you enabled kerberos/delegation, the same applies. Links One and Two
You'd have to pass in the user name as a parameter on each SQL call, or use CONTEXT_INFO perhaps.
Note: every MS Office user has MSQRY32.EXE which acts as a query tool. If you want no direct DB access, then you need to ensure there are no permissions set or granted
Depends.
If your database and WCF service are on the same box and you do a lot of jiggery pokery to impersonate then it is possible. As soon as you move your DB to another box then it stops working.
This is a known limitation and the reason is impersonation will create a token which will get you to a box but this is not passable to another box. I tried to find the Q&A where MS guy had answered but still havent been able to. Whenever I find it, will update.

SQL Server authentication - limit access to database to only connect through application

I have a database which users should not be able to alter data in unless they use the specific app. I know best practice is to use windows authentication however that would mean that users could then connect to the database using any other data enabled app and change values which would then not be audited.
Unfortunately SQL 2008 with its inbuilt auditing is not available.
Any ideas how to ensure that users cannot change anything unless its through the controlling app?
Use whatever means for users to log in. Windwos authentication encouraged.
make sure the user has no rights to change any data ;)
The application then, on the existing connection, post-authorized using application roles.
More info on that is on http://msdn.microsoft.com/en-us/library/bb669062.aspx
Basically the application can get a separate sets of rights by using an application password (that sadly has to be coded into the application - use sensible means to protect it), replacing the limited rights the user has with more rights for itself.
I would ask you to consider using an application server, but if you have a classical client/server architecture that is as good as it gets.

Resources