I have an application built with Spring and JPA/Hibernate that is working very well, but I now have a requirement to add Oracle Label Security. This will require the creation of a proxy user assigned with certain roles in addition to the actual user. I am unclear what goes into persistence.xml and what goes in code. Also, if we want to get really fancy, I would love to know how Spring can inject the proper persistence context with the mapping of user to proxy user.
If anyone has experience with this, any insight is appreciated.
thanks.
I'd approach it the following way:
First get the basics of proxy authentication straight. This article looks promising: https://blogs.oracle.com/olaf/entry/using_oracle_proxy_authenticat
Assuming you have Webapplication (or anything else with a single point of entry) create a Filter wich accepts the request, identifies the user, establishes the user in the database using proxy authentication and then forwards the request.
This way your application will only see proper connections with the correct user established. So your Hibernate configuration should not be affected by this.
One warning: You are probably using a connection pools. These pools might not hand you an Oracle implementation of JDBC, but a wrapper through which you have to gain access to the oracle specific features needed. Make sure your application still uses the wrapper other wise the connection pool will not notice any exceptions thrown by the connection, thereby not recognize broken connections and will hand them out over and over again.
Related
Thinking to how Php operates, there are both client and server 'cookies', where the server cookies are session-dependent data that is only seen by the server.
Does Quarkus have anything similar to this? I realize I could make something that would effectively produce this behavior with session client cookies, and internal data maps, but was hoping there might be something along these lines already established.
Quarkus does not really implement any specific session management. The rationale is that it is focused on Microservices, so the system should be as stateless as possible.
What is does have is support for CDI's #SessionScoped if quarkus-undertow is being used.
tl;dr
Requesting suggestions, guidelines or examples for possibilities to extend spring-boot-adminto use methods other than HTTP requests for health moitoring of non-spring projects like MariaDB.
Full version
There is a requirement to setup a monitoring application using spring-boot-admin. Several of the clients are spring-bootapplications and are easily implemented. There are however a couple of non spring-boot projects like the database server MariaDB.
The question is therefore formulated thusly : Is it possible to extend SBA to monitor the databse status by methods other than HTTP requests. One possible approach, for example, might be to check if it is possible to connect to the application specific TCP port to verify if the db server is still running. However, other possibilities can be exploited too.
One post I found similar to my question was this :
https://github.com/codecentric/spring-boot-admin/issues/504. The key difference here though is that the provided answer still sugests a HTTP approach. The reference guide also does not suggest an alternative.
Should such a possibility exists, a brief outline of the approach or an example implementation would be most welcome.
SBA currently only supports checking health via http. But your DB should be implicitly monitored if you have an according health indicator on your business application.
It should be possible to extend the StatusUpdater#queryStatus() doing a tcp connect if it encounters an health-url beginning with tcp:// instead of http://...
And in case you accomplish that a PR is appreciated :)
I am performing load balancing for my application. I have made two application servers, say A and B. That access the same database (Postgres) using Hibernate.
The problem arises when the system moves from A to B. Most of the things are working fine, but at some points (While reading data from db) the system automatically logs the user out.
Is this because of synchronization with db?
Is there some kind of lock on the database when one application is accessing the database?
What do i need to do in-order to get it working?
It'll be a great help.
While the Postgres server can terminate connections for various reasons (i.e. if an admin does so), generally that would be a client-side thing, which in your case is likely Hiberate as a Spring DAO. If your app-level login is being closed, it's likely to be an issue with how your app is logging back in on the other server.
Most likely, you have entirely separate DAO instances on each server, and so when the switch from app-server A to B occurs mid DB read, it has to start over from the beginning on the new server, including authentication, et al.
I'm assuming each is deployed in its own WAR and has the DAO injected at runtime, at which point the connection to Postgres is made. (You could add logging in your dependency-injection code to determine more.)
In addition to the separate database connections, it appears it doesn't handle failover to the other server without requiring re-logging in. That shouldn't be related directly to Postgres, at least not the connection. It would depend on how you're persisting the login. i.e. if it's cached locally, that would also have two separate instances in each app, and the authentication would need to reoccur. If the credentials are stored in Postgres, the connection would first need to be obtained before re-authenticating.
Edit in response to comment from OP:
Since they are two separate app instances, a load balancer alone would not work, since that would most likely depend on the request being (mostly) stateless. If you authenticated via a token which was either in the URL or the header, a load balancer would work, since the the auth token would be redirected also, and while reauthentication would need to happen in the backend, authentication should be granted if the token is valid, and the app should essentially stay logged in. It doesn't sound like you're using auth tokens, though.
In short, which two separate instances, the authentication really always needs to happen on every request, but how that's managed can vary. You could look into an OAuth solution, for example, but that may be overkill for your needs.
In any case, you should avoid taking state straight from the client, since that can be tampered with. If the server were to failover cleanly (say, for load purposes), you could control that security handover in the app logic by propagating the security context to the other instance, although that could get a bit unwieldy.
However, during an unclean failover (say, if the JVM heap limit is reached), that wouldn't be possible -- you would need an external authentication system that the other app could query using the supplied credentials, determine the request is authenticated, and allow the request to proceed.
I have a WebApp where users log in using the database credentials and the backend runs prefab reports on a production database using the users credentials. Company policies does not allow a technical user in this special case.
Since a Datasource is tied to one user I use a plain JDBC connection
java.sql.Connection c = DriverManager.getConnection(aUrl, aUsername, aPassword);
This works but is this the preferred way to to this in an application server? Somehow this does not seem right.
This way will make your database run out of available open connections and result sets (open cursors) as soon as the user concurrency reaches a certain threshold.
The usual way to do this would be to define a database connection pool with a certain user with the appropiate grants. This connection pool should have some config settings that feel comfortable to your DBA, and should keep its open connections in thresholds that are acceptable to your data base, so you will never get into problems in case of excessive concurrency (you should not reach a database problem with, let's say, 250 concurrent users, which is likely to happen with the method you describe in your post).
The way to achieve this would be to provide sound arguments to your database folks in order to properly review the company policies on database users, in terms of
robustness: the initial implementation will surely take your database down with its first hundreds of concurrent users - this is not possible but certain
performance: a connection pool will always outperform the initial idea because opening a new connection is a very expensive operation
ease of monitoring and administration: a technical user will allow your DBAs to instantly know and better take decisions (for example, tablespace sizing and the like) over the running queries coming to their database from the java application servers
security: actually the matter of who can order which report is a business logic problem, that should be delegated to an upper tier - once this is solved, just let the java application order its reports
Good luck with this!
I'm faced with a curious problem in my current project:
I've got multiple Spring MVC based web apps deployed on a Glassfish 3.1 server - and I need to be able to "timeout" the user based on the "sesion timeout" parameter in their respective web.xml - no matter in which application the user is on. Please don't ask why the applications are in separate WARs - the architecture is so. The user is logged in via WebApp A and is redirected to a WebApp B - and then the user can keep jumping to different web apps - I guess you get the idea. The WebAppB etc. have numerous Ajax calls (I'm not even going there) as well. The question, I guess, boils down to the fact that I'm not able to share session data between WebApp A and WebApp B (I may be wrong here - and this is where I require help) and so I don't have any way to know by checking
httpServletRequest.getSession(false)
in WebAppB since it returns null in both cases when the first request hits the WebAppB and the first request "after" a session timeout. I have to keep "something" in the WebAppA's session and check for its existence in WebAppB's session - which brings me back to the issue of sharing session data within web applications. I cannot use DB storage, since that would mean a DB call on every request. I got a direction by googling that "crossContext" thing in Tomcat helps in such scenarios - but will something like this be helpful in Glassfish ( there's a "crossContextAllowed" property for sun-web-app.xml which I recently found).
I've been stuck with this for quite some time now and I'm not even sure this is a question worth your time - so thanks in advance for trying to help.
Trishul
I cannot help you with the Glassfish implementation, but what you need is a form of Single Sign On between webapps.
To implement this form of SSO you usually need to do two things:
Make sure all your webapps share a common root context i.e webapp A is on /commonroot/webappA and webapp B is on /commonroot/webappB. The reason for this is that the same session Id must be delivered to the two webapps when the user switches between them. Session Ids are usually stored in cookies and browsers deliver cookies based on path. There must be a setting on Glassfish (as there is on Tomcat and Jetty) which can "force" webapp A to deliver a cookies on path "/commonroot" (rather than /commonroot/webappA) and webappB to do the same. Any access to webapp A or webapp B will then pull and provide the unique session id from the cookie associated with the /commonRoot path.
Once you have all your webapps within the same 'SSO context' share a common session for an user, you need to have these webapps access the session from a common, unique store. A DB is a usual way to do it but if you are looking for speed, something like memcached or hazelcast may be more appropriate. The advantage of using a DB is that it additionally provides session persistence: if your session store is bounced, an user making a call with a session which is not expired will be transparently reconnected without having to login again.
Servlet/JavaEE containers usually provide samples of SSO Realms/SessionManagers or equivalent that will directly implement what you require or that you can hack to fine tune to your needs.