Oracle - Get authenticated user - oracle

My MVC application connects in Oracle database. We created a lot of triggers to save all data changed by users.
inside the trigger, we used the code bellow to get authentcated user:
UPPER(SYS_CONTEXT('USERENV', 'OS_USER'))
When i'm running my application in localhost, the database get the correct user, but when i plublish it on server (IIS), the database always get as user the application pool name.
Is there some IIS configuration that i need to set to get "Windows authentication" user? Is there another way to get this information inside oracle function/trigger?

You would realistically want to use a secure application context which is basically a user-controlled context unlike the system-controlled USERENV context. When the application code gets a connection from the pool, it would call a stored procedure that sets the application username in the new application context. Your triggers would then reference the new context rather than USERENV. Your application needs to ensure that the context is set appropriately every time a connection is acquired from the pool-- if the application fails to set the context correctly, your triggers will get the wrong information.
If you don't want to create your own context, you could use the CLIENT_IDENTIFIER in USERENV which you can set via dbms_session whenever you get a connection from the pool. Functionally, this is basically identical to creating your own context. The nice thing about creating your own context, though, is that you can seamlessly add attributes in the future as you identify the need (i.e. adding the IP address of the client browser or a tier attribute if you have gold, silver, and bronze customers).
There are alternate ways to approach the problem such as using proxy authentication. In general, though, that's not going to work as well with connection pools particularly when you have very large numbers of users.

Related

How to view server connections of a session or workflow

As an SQA, I need to verify that all connections associated with a set of workflows have been updated. How can I view all connections associated with a workflow? Is there a connection, or connections, assigned to individual workflows, or would I need to find the connections for each individual session? If so, how do I view the connection(s) of a session?
There may be plenty connections used by a single session - that's very often the point of ETL and data integration. Those connections used in session (or sessions!) may be defined in this session. But a session can use parameter for the connection that will be replaced with some value defined in a parameter file. A parameter file can be defined on the session itself, or it can be defined for a workflow. Or there can be some external utility that stores the configuration and executes the workflow with a generated parameterfile that you will not find in the workflow definition at all.
There are some tools that would help you get all the connections for a session or all sessions in a workflow, but deriving the values for the parameters is more difficult. You need to know where they come from in your environment.
Please note that workflows and sessions hold the connection name only - where does it actually connect depends on the connection definition.
In addition, the very same workflow and sessions can be executed with different connection values, e.g. to perform the same set of operations on a different set of sources and/or targets.

Is a serviced component shared between user sessions on a terminal server, or is one process started for each user session?

I have some .NET code in a COM+/Enterprise Services serviced component. I communicate with this component from a WPF application and also from a legacy VBA application.
This arrangement works well when only one user is logged on to a machine. The component starts in its own process when either the .NET or the legacy application instantiates one of its COM objects.
The system also works for the first user to try to run it on a terminal server installation. However, when another user logs on, he/she is unable to use the application. I had hoped that each session would run in isolation, and that one host process would run per session. Am I wrong in this expectation?
In Component Services on the Activation tab my application is configured to run as a "Server application". On the Identity tab, "Interactive user" is selected. On the Security tab, "Enforce access checks for this application" is unchecked.
There isn't session isolation as you describe, instead process ownership limits what you have access to.
Your conclusion seems correct & you will need to determine a suitable mechanism to exchange data with the service.
I used WCF to create a service with a net named pipe listener https://learn.microsoft.com/en-us/dotnet/framework/wcf/index
The idea of using proxies to make rpc calls is attractive, but I found the proxy definitions and stubs to link it all together quite clumsy to use.
If you have events that may be triggered at either end then keeping client/service in sync becomes problematic.
AIUI you cannot invoke a rpc method that ends up invoking an rpc back at the originating end, although that could be a named pipe limitation.
If I was doing this again I would use a socket server in the service & the websocket protocol for biderectional data transfer, even though you might need to implement some thread handling to avoid the listener thread blocking whilst servicing requests.
Hard to find anything authoritative on this. For standard COM you can set the identity to 'Launching user'. The same is not available for COM+.
According to this archived post,
A COM+ application can be configured to run under the logged in account, or
a specified account. Under the application properties, see the Identity tab.
...
Once set however, it remains under that account until the application shuts
down, so you can't have multiple users using the same COM+ application under
different IDs.
That seems to match what is said in this knowledge base article too.
My conclusion is, I should probably accept that my component must run once per machine rather than once per session. It will need to be modified to accommodate this. Since it needs to start new processes in individual sessions, it will have to run as a Windows service under the Local System account (giving due attention to the security implications).

Oracle session is being shared by different web clients - weblogic

This is causing issues as our procedures use session based global temp tables; need that for good reason. The actions of one web client interferes with that of another. Why is the same Oracle session reused by a separate client.
There is connection pooling with Web logic in place. I have printed the following to confirm that indeed 2 clients are being assigned same oracle session.
SELECT SYS_CONTEXT ('USERENV', 'INSTANCE'),
SYS_CONTEXT ('USERENV', 'SID'),
SYS_CONTEXT ('USERENV', 'SESSIONID')
FROM DUAL;
How to ensure each client gets a different session (not HTTP session, but Oracle session)? Is this something at Weblogic level that needs to be modified?
If you're using connection pooling in the middle tier, then once your middle tier code closes a connection, it is returned to the pool and is available to be used by another middle tier session. If you are trying to use global temporary tables that store data past the point that the middle tier closes a connection, you're doing something wrong.
You could design and build your middle tier so that it doesn't use connection pooling and so that each middle tier session opens a private database connection that is used only by that user. That would generally be a horrible idea, however, since you would generally end up spending oodles of time opening and closing database connections, you'd end up with thousands of orphaned database connections when an application user simply navigates away from the site rather than explicitly logging out, and it would become very difficult to do things like have the same user serviced by different app servers at different points in time for load balancing purposes.
A better approach would be to get rid of the global temporary table and store whatever data you need in a permanent table that includes your unique session ID as part of the key. You'd need to write code to purge the data at some point but that shouldn't be terribly difficult.

JDBC connection pool manager

We're in the process of rewriting a web application in Java, coming from PHP. I think, but I'm not really sure, that we might run into problems in regard to connection pooling. The application in itself is multitenant, and is a combination of "Separate database" and "Separate schema".
For every Postgres database server instance, there can be more than 1 database (named schemax_XXX) holding more than 1 schema (where the schema is a tenant). On signup, one of two things can happen:
A new tenant schema is created in the highest numbered schema_XXX database.
The signup process sees that a database has been fully allocated and creates a new schemas_XXX+1 database. In this new database, the tenant schema is created.
All tenants are known via a central registry (also a Postgres database). When a session is established the registry will resolve the host, database and schema of the tenant and a database session is established for that HTTP request.
Now, the problem I think I'm seeing here is twofold:
A JDBC connection pool is defined when the application starts. With that I mean that all databases (host+database) are known at startup. This conflicts with the signup process.
When I'm writing this we have ~20 database servers with ~1000 databases (for a total sum of ~100k (tenant) schemas. Given those numbers, I would need 20*1000 data sources for every instance of the application. I'm assuming that all pools are also, at one time or another, also started. I'm not sure how much resources a pool allocates, but it must be a non trivial amount for 20k pools.
So, is it feasable to even assume that a connection pool can be used for this?
For the first problem, I guess that a pool with support for JMX can be used, and that we create a new datasource when and if a new schemas_XXX database is created. The larger issue is that of the huge amount of pools. For this, I guess, some sort of pool manager should be used that can terminate a pool that have no open connections (and on demand also start a pool). I have not found anything that supports this.
What options do I have? Or should I just bite the bullet and fall back to an out of process connection pool such as PgBouncer and establish a plain JDBC connection per request, similar to how we're handling it now with PHP?
A few things:
A Connection pool need not be instantiated only at application start-up. You can create or destroy them whenever you want;
You obviously don't want to eagerly create one Connection pool per database or schema to be open at all times. You'd need to keep at least 20000 or 100000 Connections open if you did, a nonstarter even before you get to the non-Connection resources used by the DataSource;
If, as is likely, requests for Connections for a particular tenant tend to cluster, you might consider lazily, dynamically instantiating pools, and destroying them after some timeout if they've not handled a request for a while.
Good luck!

Persisting user data in MVC 3

I have been given a requirement to persist user data once the user has authenticated initially. We don't want to hit the database to look up the user every time they navigate to a new view etc...
I have a User class that is [Serializable] so it could be stored in a session. I am using SQL server for session state as well. I was thinking of storing the object in session but I really hate doing that.
How are developers handling this type of requirement these days?
Three ways:
Encrypting data in cookies and sending it to client, decrypting it whenever you need it
Storing it server side by an Id (e.g UserId) in Cache, Session, or any other storage(which is safer than cookie).
Use second level caching strategy if you used an ORM
Assuming your user object is not huge and does not change often i think it is acceptable to store it in the session.
Since you already have a sql server session you will be making SP calls to pull/push the data already and adding a small object to that should have minimal perf issues compared to other options like persisting it down to the client and sending it back on every request.
I would also consider the server a much more secure place to keep this info.
You want to minimize the number of times you write to the session(request a lock) when it is stored in sql as it is implemented in a sealed class that exclusivity locks the session. If any of your other requests in this session require write access to the SQL session they will be blocked by the initial request until it releases the session lock. (there are some new hooks in .NET 4 for allowing you to change the SessionStateBehavior in the pipeline before the session is accessed)
You might consider a session state server (appfabric) if perf of your SQL session store is an issue.

Resources