cancel
Showing results for 
Search instead for 
Did you mean: 

Discussion on Re-authentication for long running transaction

ryu
Champ in-the-making
Champ in-the-making
Hi all,

Here I want to discuss about re-authentication for long running transaction in a situation as follows:

In our project, we use Activiti process as a central orchestration to call our EJBs. From my knowledge of Activiti, for handling long running transaction, the process is divided into small transactions. For example, when the process enters a UserTask, all current process's variables are commited into the database, the current transaction ends and the process goes into a wait state. When a user finishes his form, a new transaction is started again.

Our designer has different EJBs and an authentication is performed before invoking any of them. The problem is the authentication information of EJB is hold in a thread. But when your transaction ends, and you start a new transaction (new thread) after that, you will loose your authentication information. In another words, when Activiti starts a new transaction after a UserTask, how can we call an EJB with the authentication information of the previous transaction.

I'd love to hear your ideas.

Thank you very much
Regards
13 REPLIES 13

jbarrez
Star Contributor
Star Contributor
If your EJB authenication information is kept in a thread local, then you would also have problems in webservers that use a threadpool, no?

One obvious approach would be to store athentication details in the process itself.

ryu
Champ in-the-making
Champ in-the-making
Sorry Jbarrez that I have to awake this topic again. We still cannot find a good solution.

Principal or authentication details are safe when they stay in EJB context or Security-context. If they are set in the process itself as a process variables. Then there are possibilities that a Thread set a principal from another user to gain another authentication.

Development of business process means to deal with long running transaction (usertask etc), how can a process deal with this problem when Thread Local time out and authentication details lost? Is there a common concept for process security, not only for Activiti?

frederikherema1
Star Contributor
Star Contributor
I did a similar thing for the Alfresco-integration, having a modified version of the jobExecutor plugged in. This enables timers to execute in the alfresco-security context of the task's assignee (if any) or the process initiator. In this solution, the username is stored in the process itself (assignee of current task or initiator) and when jobexecutor runs it "assumes" authentication.

Since the engine runs inside alfresco, and NO authentication secrets (like passwords) are stored in the activiti DB, I see no issues. Even if it where, if people have access to raw DB, you have other issues than possibility to run a process async with the wrong security-context Smiley Wink

Other than that, I don't know of any standard (be it activiti-specific) way of handling this kind of problem…

ancoron
Champ in-the-making
Champ in-the-making
That is a very common problem for JavaEE applications that are "security-enabled" and also very useful for auditing. Most companies I've worked in then decided to not secure too much, which is kind of *WTF?!*.

So as there are no generic solutions available I've already started to implement a kind of "sudo" mechanism for GlassFish 3.1+. For that I'm using the mechanisms of "javax.security.auth.Subject" and "javax.security.auth.login.LoginContext" to do a real login inside the server (to automatically get all the groups/roles). Additionally I'm using the vendor-specific "SecurityContext" (apparently there is no standard here) to store the old information (the process itself), then create a new one for the thing to do as the original user and after that, restoring the process SecurityContext.

The only problem with it is, that I didn't have enough time to come up with a solution other than username/password (to login) for now. In GlassFish, there already is a ProgrammaticLogin class. However, that doesn't do the real thing, so you need a real login and hence, real authentication data.

My current plan is to implement something like a X.509-cert-based sudo, which would mean that you have to create and store private and public credential information, where only the "sudo"-service itself has access to the private part and can use it for authentication (this avoids the plain-text password approach). On the other hand, one could also implement a less secure token-based authentication type (using a token as a password, which was generated in the beginning of the process).

However, all those things would require an additional LoginModule to be plugged in to the appropriate security realm of the application server (they all support LoginModule chains). So I guess, a single generic implementation that works on all application servers/platforms is not possible atm.

Here is my very basic implementation: https://github.com/ancoron/javaee-tests

Using Maven you can get the binaries from here: https://oss.sonatype.org/content/groups/public/org/ancoron/javaee/

So I think you'll get the idea.

Cheers,
Ancoron

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
That is a very common problem for JavaEE applications that are "security-enabled" and also very useful for auditing.
Authentication and Auditing are two different but (partly) related things

Most companies I've worked in then decided to not secure too much, which is kind of *WTF?!*.
You should never secure 'to much', you should secure 'enough'.

I wrote 'partly' above since there is one major concept with security and that is 'trust'. In your example you 'trust' the application to be the only one to have access to the store with security tokens. Now where does this application get's the info on deciding where to get the credentials that are needed to re-authenticate to an external system on behalf of a user (cause that is what your usecase is, right). Well, it gets it from? A process engine variable? A different database? In that case the trust of the application is as good as the trust you have in information in the database. So… why not make sure you trust the application (give IT a login) and have it pass the information on who's behalf it is doing something to the external system and use that info in auditing.

Sounds weird? Sounds like 'not enough security'? Well it is *not*, serious auditors of insurance companies accept this, while they would *no*' accept storing credentials of others in a system, readable, usable etc. That would be a major issue if stolen.

ancoron
Champ in-the-making
Champ in-the-making
Nice to get some decent reply to my proposal. I really need feedback here. 🙂

That is a very common problem for JavaEE applications that are "security-enabled" and also very useful for auditing.
Authentication and Auditing are two different but (partly) related things
No. Really? … just kidding… 😉

Most companies I've worked in then decided to not secure too much, which is kind of *WTF?!*.
You should never secure 'to much', you should secure 'enough'.

…with "too much" in my previous experiences I meant: "not at all". The only "security" there was either the user-name or group, being part of the method parameters or a completely self-written thing that tries to redo, what has already been done within the various JavaEE implementations, but even more crappy.

So… why not make sure you trust the application (give IT a login) and have it pass the information on who's behalf it is doing something to the external system and use that info in auditing.

What I would like to achieve is being able to make use of all those neat security-related annotations in my EJB's I'm going to access by the processes and also use the standards to transport relevant data across calls for auditing/monitoring/logging/…

So exactly the part "on who's behalf it is doing something" is the core problem to be solved in a transparent and (most preferably) implementation-agnostic manner (although my implementation is already tied to GlassFish, other may follow easily or being replaced by a completely generic approach). The processes itself are running as a default "process" user, which basically has no access right, but the right to "sudo".

So as you can see I didn't implement the credential thing yet, as I am quite unsure which kind of trust I should implement. So going directly into the topic you mentioned: the chain of trust.

I seriously don't want to break anything by design, so my initial plan was to either assume a pre-filled key-store (where the unique username matches the certificates subject) or generating short-lived private/public key pairs on demand containing a session ID or the process instance ID itself inside the subject. Using an appropriate LoginModule I can then verify if an incoming certificate matches against all kinds of restrictions.

One should really take care of the part that actually generates the certificates. Using an external system to sign them would also be possible to have control over it (unsigned certificates won't be accepted by the LoginModule) and even the generation itself could be part of an external system.

As a start I was imagining to "trust" a logged in user for the certificate generation part.

However, this is not intended to be a high-security solution. What I was basically thinking of is "just" to do a "real" login (from a JACC/JAAS point of view) at the server-side without requiring user interaction and at the same time being able to hook into the (granting) process and gain control (the use of external systems should be supported for this).

This is not much different than generating your private/public SSL key-pair and using a password to "ssh-copy-id" it onto a server using your password and after that you're able to login without any password and can also write scripts to automate things using remote access.

So in the end I "only" see the following problems with this approach (security-wise):
  • The certificate generating part (the initiator has to be verified - could be a valid request from some logged in user)
  • The certificate reading part (one will have to ensure, that there is no way - from an application point of view - to read the certificate from a user different than that the current process instance identifies - high risk here)
  • The "variable" for the user/session-id has to be read-only (also high-risky)
Sounds weird? Sounds like 'not enough security'? Well it is *not*, serious auditors of insurance companies accept this, while they would *no*' accept storing credentials of others in a system, readable, usable etc. That would be a major issue if stolen.

Hm, every application where someone logs into has access to the clear-text password. Although stored inside some password-store protected using hashing, but the application generates the hashes to be compared. And from what? The clear-text password. So that's the bigger security hole from my point of view. Things would be much easier if all "valid" users would use client-certificates.

In addition how does Single-Sign-On usually work? Or "Security" tokens? They all are based on some method to read data which is then processed and compared to something else, so either way you are always going to store sensible data in one form or the other. The initial "reading" part is always clear-text (at least for the application part) and hence can be misused.

The fact that "serious auditors of insurance companies accept this" is only because it is common practice as well as a trade-off in security vs. development time (vs. investment of money vs. interest of management in this). It's sad, but "high-security" is still not "high-priority" in the heads of management, even nowadays.

However, I don't want to build the ultimate uncrackable thing here, just a way to re-authenticate from scratch, without having the need to store sensible information in plain-text inside the process. In the end I'm just building a tool. What the tools does should be clear, how it is being used is completely up to the application developer.

But your answer convinced me to also do an experiment with a simpler, SSO-like approach using a session token and/or "activity"-tokens, that should be easier to be implemented on both sides and basically follow the idea of the WSS UsernameToken Profile.


Cheers,

Ancoron

P.S.:

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
Hm, every application where someone logs into has access to the clear-text password.
The application should not have access to it, just the authentication layer.

The fact that "serious auditors of insurance companies accept this" is only because it is common practice as well as a trade-off in security vs. development time (vs. investment of money vs. interest of management in this).
Sorry, no. I is accepted because it is a valid pattern. It is not that there is *no* authentication, since the application authenticates itself against external systems instead 're-authenticating' the end user.

It's sad, but "high-security" is still not "high-priority" in the heads of management, even nowadays.
This is not true in general. In many companies I worked with it does have highpriority and things do get implemented correctly. One of the major things with security in relation to developing applications is to keep things a simple as possible so mistakes are easily caught.

The 'solutions' like te ones you describe are equally and mor insecure since the *real* user cridentials are stored in a central system, not under the users control. Yes, you can legally make this central storage en extension of the user space, but that adds additional complexity to a solution that already is more complex.

Using wss profiles like a saml bases sso solution and use those tokens… Still, (ab) using real credentials does not feel right. For several reasons… They have a limited lifespan, so what if one expires? Or if the user logs out in between, then the token also becomes invalid.

Authenticating the application (trusting it) and having it pass the id of the user on who's behalf something is done, is safe and simple.

But that's just my two cents

ancoron
Champ in-the-making
Champ in-the-making
Hm, every application where someone logs into has access to the clear-text password.
The application should not have access to it, just the authentication layer.
I totally agree here, however, every Java web-application actually has, although you have to unwrap some interfaces, unless you do the authentication before entering the Java space. That's why initially the clear-text password transported in some request has been stored using a char array, which can be deleted and overwritten in memory, hence can be really get rid of once authentication is done to avoid leaking passwords in memory.

The fact that "serious auditors of insurance companies accept this" is only because it is common practice as well as a trade-off in security vs. development time (vs. investment of money vs. interest of management in this).
Sorry, no. I is accepted because it is a valid pattern. It is not that there is *no* authentication, since the application authenticates itself against external systems instead 're-authenticating' the end user.
I see your point. However, I don't consider a password to be a serious information of trust. The only thing that prevents me from replacing password-based authentication with client-certificate-based is because it is common practice and hence validates itself as a use case I have to cover.

It's sad, but "high-security" is still not "high-priority" in the heads of management, even nowadays.
This is not true in general. In many companies I worked with it does have highpriority and things do get implemented correctly. One of the major things with security in relation to developing applications is to keep things a simple as possible so mistakes are easily caught.
Nice to hear, really. I have made experience on the other end.

The 'solutions' like te ones you describe are equally and mor insecure since the *real* user cridentials are stored in a central system, not under the users control. Yes, you can legally make this central storage en extension of the user space, but that adds additional complexity to a solution that already is more complex.
Yes, I know that there is a problem in there by concept and I really would have to take care that misuse is being prevented.

Did you ever happen to secure your EJB's using either standard configuration or annotations? The problem is simple: an EJB is secured and certain methods only accessible to authenticated users that belong to a certain group/role. And exactly here is the problem: the user-to-roles mapping, which I would have to transport as well and somehow "set" them along with the user itself before invoking such a secured EJB.

This would involve digging into the application servers code and find a way to set them programmatically. The GlassFish guys provide a simple class to "fake-authenticate" a user, however, they clearly state that this doesn't involve any real authentication and hence, no user/role mapping coming from e.g. a database or an external system.

So, to access such an EJB when a process takes hours, days, or even weeks, I have to authenticate the real way. If I only had processes that deal with rather short-running non-background transactions initiated by e.g. user-tasks, I could simply re-use the authenticated request of the user that completed a user-task. However, in my current case I have a distributed system that is highly automatic using timers to pick up tasks for a user.

Using wss profiles like a saml bases sso solution and use those tokens… Still, (ab) using real credentials does not feel right. For several reasons… They have a limited lifespan, so what if one expires? Or if the user logs out in between, then the token also becomes invalid.

Authenticating the application (trusting it) and having it pass the id of the user on who's behalf something is done, is safe and simple.
Yes, it's simple. However, it's not so simple in my case and simply wouldn't work.

Cheers,

Ancoron

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
I see your point. However, I don't consider a password to be a serious information of trust. The only thing that prevents me from replacing password-based authentication with client-certificate-based is because it is common practice and hence validates itself as a use case I have to cover.
Then I'm lucky, we had (and have both). But with a decent sso solution, it does not make a difference from the application point of view.

Did you ever happen to secure your EJB's using either standard configuration or annotations? The problem is simple: an EJB is secured and certain methods only accessible to authenticated users that belong to a certain group/role. And exactly here is the problem: the user-to-roles mapping, which I would have to transport as well and somehow "set" them along with the user itself before invoking such a secured EJB.
Yes and no. What we did in an early stage is to get rid of the 'dogma' that at the ejb level, individual users should be authenticated. That is where we authenticated the calling application (if it was a remote call). The user (and his roles) is passed on in a standardized way (SAML token), not via methods, but via threadlocal (a strong concept! appservers use it themselves all the time). But something like http://docs.jboss.org/seam/3/security/latest/reference/en-US/html/ is also an option

[quoteThis would involve digging into the application servers code and find a way to set them programmatically. The GlassFish guys provide a simple class to "fake-authenticate" a user, however, they clearly state that this doesn't involve any real authentication and hence, no user/role mapping coming from e.g. a database or an external system.] Well, not realy. It is not difficult (assuming ejb 3.0) to create your own annotations. This works cross appserver and the annotations read the threadlocal variable with the user details.

So, to access such an EJB when a process takes hours, days, or even weeks, I have to authenticate the real way.
This is where we differ in view. I do not need real authentication of the enduser, I need the guarantee that the calling application can be trusted that what it says it is working on behalf of is true.

If I only had processes that deal with rather short-running non-background transactions initiated by e.g. user-tasks, I could simply re-use the authenticated request of the user that completed a user-task.
…. if only…. 🙂

However, in my current case I have a distributed system that is highly automatic using timers to pick up tasks for a user.
ours is to (or rather 'theirs' since I do not work there anymore and where I work now, we will be putting these kinds of concepts into place comming months)

Yes, it's simple. However, it's not so simple in my case and simply wouldn't work.
I there are existing systems out of your control then I can imagine. If there are existing systems within your control, I'd seriously think of adapting those 😉

For remote calls it is a different thing all together, but luckily these were already designed to use 'application level security'