You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by Randy Watler <wa...@wispertel.net> on 2009/02/09 10:41:45 UTC

SSO PasswordCredential Question

Ate/Dennis,

In SSOManagerImpl.setPassword(), we invoke 
PasswordCredential.setPassword(xxx, false) from 
TestSSOManager.testCredentials() and then requery the password later in 
the test to see if it has changed.

This works fine with OBJ, but with JPA I get the same PasswordCredential 
instance back on the requery because it is in an 
'Extended'/'Conversational' transaction. As a result, the 'new password 
set' transient tracking in PrincipalCredentialImpl is active and is as 
if the user just set the password. This means that the 
PasswordCredential.getPassword() returns the previous password value and 
the test fails.

I am wondering if immediately after the PasswordCredential.setPassword() 
call the SSOManagetImpl.setPassword() method should invoke 
PasswordCredential.clearNewPasswordSet()? That seems like it might make 
sense in this case since we're forcing a password change, no?

Randy


---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Re: SSO PasswordCredential Question

Posted by Randy Watler <wa...@wispertel.net>.
Ate,

One purpose of an extended/conversational entity manager, (i.e. long 
transactions), is to cache versions of attached objects that have been 
accessed during its lifetime. This means that things like object level 
'==' operations can be used to imply object identity. Obviously, that is 
natural for POJO style Java coding. In the test harnesses, the default 
lifetime is established per test thread. In the portal, we have choices 
to make there, but I envision it to be roughly analogous to portal 
requests. It does not matter when commits or rollbacks are made against 
the entity manager, the attached objects span its entire lifetime. The 
Seam framework utilizes this approach to minimize the attach/detach 
operations that would be otherwise necessary as code crossed various 
transactional proxy boundaries.

So, yes, the exact same object instance is returned by JPA in this mode 
whether the object is about to be or has been committed. As you can 
imagine, this caused unexpected behavior with the transient tracking 
members in PasswordCredentialImpl. If we want the credential to clear 
its state on a commit, we should do that explicitly. In the past, we 
relied on subsequent gets returning brand new instances which had their 
"new password" state cleared. This is a difference between OJB and the 
conversational JPA approach. So would it be correct then to invoke 
PasswordCredentialImpl.clearNewPasswordSet() when the object is written 
to the database? At least then the dirty credential would be left in the 
same state after a commit that a new credential fetched from the DB 
would be in... that seems more consistent than the current 
implementation. All of the managers and interceptors you discussed below 
should have already processed the credential by the time it commits, no?

As you can tell, I am nervous about the "OJB" hangover in our code base 
and am trying to get it right from a conversational JPA POV. One other 
interesting fact about JPA caching is that no instance is EVER shared 
between entity managers. There is a cache, but it stores objects as a 
list of fields that are used to reload new objects for each 
conversational entity manager scope. At first, I was dismayed by this, 
but it is handy when you think about the transient state management 
issues that can come up otherwise. I am not sure how you intended the 
transient tracking of PasswordCredentialImpl to operate from an 
isolation perspective, but I am pretty sure it is safe to think about it 
as having the scope of one conversation/thread/request.

With regard to the test case we have been discussing, I did force it to 
utilize separate transactions/conversations to initially create the sso 
user+credential, to set a new password, and to validate the fact the 
password was changed. This makes the test run more like OBJ does and new 
conversation-specific instances of the user and credential are operated 
on and validated in each step. Of course, this makes it a more realistic 
test case as you point out, (normally these would happen in 3+ requests 
into the portal).

I hope this answers some of your questions and fills in some background. 
I might be a bit off in my explanation in the dark corners here and 
there, but you should get the idea where I am coming from in any case. 
Please consider my proposal to clean up the transient state of 
PasswordCredentialImpl on commit, (persist/update). It may not make any 
difference to you or OJB, but I'd sleep better knowing that the internal 
state of these conversational attached objects is maintained in a 
consistent manner.

Thanks,

Randy

Ate Douma wrote:
> Randy/Dennis,
>
> I just responded before on the initial question from Randy when I saw 
> this one :)
>
> Some additional comments inline below.
>
> Randy Watler wrote:
>> Dennis/Ate,
>>
>> The credential is not transient. It is persistent and I verified it 
>> was written to the database. The "feature" is that setting a password 
>> is deferred by transient tracking members in PasswordCredentialImpl. 
>> With OBJ, a new credential instance is read from the DB on every 
>> access and that circumvents the set password tracking. With JPA, the 
>> objects are cached. Within the same transaction, you are ensured of 
>> getting the same instance back, even if it has been flushed to the 
>> database on a commit. 
> Even *after* an instance its state has been committed?
> I would think that would end the transactional state/cache too, thus a 
> subsequent read would reload the previously committed state?
>
>> Because its the same instance, the getPassword() access retrieves the 
>> old value, despite the fact that the credential has in fact been 
>> updated.
> As I mentioned in my previous response, would it be possible to use 
> (force) multiple transactions for this (and possibly other) test 
> cases, which would be more realistic from a (user) interaction POV too?
>
>>
>> I do not want to do something that is wrong here. The deferred 
>> password set operation is there for a reason no doubt, but I am 
>> wondering if it is safe to override that capability in this case. 
>> Perhaps Ate can comment on why PasswordCredential does this in 
>> general and if it is appropriate to disable it here?
> As I already explain in previous response, it think it would *not* be 
> appropriate to do so.
> PasswordCredential handling is somewhat special because a 
> PolicyManager and/or PasswordCredentialInterceptors could be 
> configured which might need to have their say in the validation (and 
> storage) of an new/updated PasswordCredential.
> By "clearing" the passwordSet state directly from the (higher level) 
> API, this would be break the "contract" of their usage.
>
>>
>> Randy
>>
>> Dennis Dam wrote:
>>> Hi Randi,
>>>
>>> it's fine by me if you don't have other options. I guess you can't 
>>> (or don't want to) force a write-through of the password, and 
>>> discard the transient credential?
>>>
>>> regards,
>>> Dennis
>>>
>>> -----Oorspronkelijk bericht-----
>>> Van: Randy Watler [mailto:watler@wispertel.net]
>>> Verzonden: ma 9-2-2009 10:41
>>> Aan: Jetspeed Developers List
>>> Onderwerp: SSO PasswordCredential Question
>>>  
>>> Ate/Dennis,
>>>
>>> In SSOManagerImpl.setPassword(), we invoke 
>>> PasswordCredential.setPassword(xxx, false) from 
>>> TestSSOManager.testCredentials() and then requery the password later 
>>> in the test to see if it has changed.
>>>
>>> This works fine with OBJ, but with JPA I get the same 
>>> PasswordCredential instance back on the requery because it is in an 
>>> 'Extended'/'Conversational' transaction. As a result, the 'new 
>>> password set' transient tracking in PrincipalCredentialImpl is 
>>> active and is as if the user just set the password. This means that 
>>> the PasswordCredential.getPassword() returns the previous password 
>>> value and the test fails.
>>>
>>> I am wondering if immediately after the 
>>> PasswordCredential.setPassword() call the 
>>> SSOManagetImpl.setPassword() method should invoke 
>>> PasswordCredential.clearNewPasswordSet()? That seems like it might 
>>> make sense in this case since we're forcing a password change, no?
>>>
>>> Randy
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
>>> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
>>>
>>>
>>>
>>>
>>>   
>>> ------------------------------------------------------------------------ 
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
>>> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
>> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Re: SSO PasswordCredential Question

Posted by Ate Douma <at...@douma.nu>.
Randy/Dennis,

I just responded before on the initial question from Randy when I saw this one :)

Some additional comments inline below.

Randy Watler wrote:
> Dennis/Ate,
> 
> The credential is not transient. It is persistent and I verified it was 
> written to the database. The "feature" is that setting a password is 
> deferred by transient tracking members in PasswordCredentialImpl. With 
> OBJ, a new credential instance is read from the DB on every access and 
> that circumvents the set password tracking. With JPA, the objects are 
> cached. Within the same transaction, you are ensured of getting the same 
> instance back, even if it has been flushed to the database on a commit. 
Even *after* an instance its state has been committed?
I would think that would end the transactional state/cache too, thus a subsequent read would reload the previously committed state?

> Because its the same instance, the getPassword() access retrieves the 
> old value, despite the fact that the credential has in fact been updated.
As I mentioned in my previous response, would it be possible to use (force) multiple transactions for this (and possibly other) test cases, 
which would be more realistic from a (user) interaction POV too?

> 
> I do not want to do something that is wrong here. The deferred password 
> set operation is there for a reason no doubt, but I am wondering if it 
> is safe to override that capability in this case. Perhaps Ate can 
> comment on why PasswordCredential does this in general and if it is 
> appropriate to disable it here?
As I already explain in previous response, it think it would *not* be appropriate to do so.
PasswordCredential handling is somewhat special because a PolicyManager and/or PasswordCredentialInterceptors could be configured which 
might need to have their say in the validation (and storage) of an new/updated PasswordCredential.
By "clearing" the passwordSet state directly from the (higher level) API, this would be break the "contract" of their usage.

> 
> Randy
> 
> Dennis Dam wrote:
>> Hi Randi,
>>
>> it's fine by me if you don't have other options. I guess you can't (or 
>> don't want to) force a write-through of the password, and discard the 
>> transient credential?
>>
>> regards,
>> Dennis
>>
>> -----Oorspronkelijk bericht-----
>> Van: Randy Watler [mailto:watler@wispertel.net]
>> Verzonden: ma 9-2-2009 10:41
>> Aan: Jetspeed Developers List
>> Onderwerp: SSO PasswordCredential Question
>>  
>> Ate/Dennis,
>>
>> In SSOManagerImpl.setPassword(), we invoke 
>> PasswordCredential.setPassword(xxx, false) from 
>> TestSSOManager.testCredentials() and then requery the password later 
>> in the test to see if it has changed.
>>
>> This works fine with OBJ, but with JPA I get the same 
>> PasswordCredential instance back on the requery because it is in an 
>> 'Extended'/'Conversational' transaction. As a result, the 'new 
>> password set' transient tracking in PrincipalCredentialImpl is active 
>> and is as if the user just set the password. This means that the 
>> PasswordCredential.getPassword() returns the previous password value 
>> and the test fails.
>>
>> I am wondering if immediately after the 
>> PasswordCredential.setPassword() call the SSOManagetImpl.setPassword() 
>> method should invoke PasswordCredential.clearNewPasswordSet()? That 
>> seems like it might make sense in this case since we're forcing a 
>> password change, no?
>>
>> Randy
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
>> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
>>
>>
>>
>>
>>   
>> ------------------------------------------------------------------------
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
>> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Re: SSO PasswordCredential Question

Posted by Randy Watler <wa...@wispertel.net>.
Dennis/Ate,

The credential is not transient. It is persistent and I verified it was 
written to the database. The "feature" is that setting a password is 
deferred by transient tracking members in PasswordCredentialImpl. With 
OBJ, a new credential instance is read from the DB on every access and 
that circumvents the set password tracking. With JPA, the objects are 
cached. Within the same transaction, you are ensured of getting the same 
instance back, even if it has been flushed to the database on a commit. 
Because its the same instance, the getPassword() access retrieves the 
old value, despite the fact that the credential has in fact been updated.

I do not want to do something that is wrong here. The deferred password 
set operation is there for a reason no doubt, but I am wondering if it 
is safe to override that capability in this case. Perhaps Ate can 
comment on why PasswordCredential does this in general and if it is 
appropriate to disable it here?

Randy

Dennis Dam wrote:
> Hi Randi,
>
> it's fine by me if you don't have other options. I guess you can't (or don't want to) force a write-through of the password, and discard the transient credential?
>
> regards,
> Dennis
>
> -----Oorspronkelijk bericht-----
> Van: Randy Watler [mailto:watler@wispertel.net]
> Verzonden: ma 9-2-2009 10:41
> Aan: Jetspeed Developers List
> Onderwerp: SSO PasswordCredential Question
>  
> Ate/Dennis,
>
> In SSOManagerImpl.setPassword(), we invoke 
> PasswordCredential.setPassword(xxx, false) from 
> TestSSOManager.testCredentials() and then requery the password later in 
> the test to see if it has changed.
>
> This works fine with OBJ, but with JPA I get the same PasswordCredential 
> instance back on the requery because it is in an 
> 'Extended'/'Conversational' transaction. As a result, the 'new password 
> set' transient tracking in PrincipalCredentialImpl is active and is as 
> if the user just set the password. This means that the 
> PasswordCredential.getPassword() returns the previous password value and 
> the test fails.
>
> I am wondering if immediately after the PasswordCredential.setPassword() 
> call the SSOManagetImpl.setPassword() method should invoke 
> PasswordCredential.clearNewPasswordSet()? That seems like it might make 
> sense in this case since we're forcing a password change, no?
>
> Randy
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
>
>
>
>
>   
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


RE: SSO PasswordCredential Question

Posted by Dennis Dam <d....@onehippo.com>.
Hi Randi,

it's fine by me if you don't have other options. I guess you can't (or don't want to) force a write-through of the password, and discard the transient credential?

regards,
Dennis

-----Oorspronkelijk bericht-----
Van: Randy Watler [mailto:watler@wispertel.net]
Verzonden: ma 9-2-2009 10:41
Aan: Jetspeed Developers List
Onderwerp: SSO PasswordCredential Question
 
Ate/Dennis,

In SSOManagerImpl.setPassword(), we invoke 
PasswordCredential.setPassword(xxx, false) from 
TestSSOManager.testCredentials() and then requery the password later in 
the test to see if it has changed.

This works fine with OBJ, but with JPA I get the same PasswordCredential 
instance back on the requery because it is in an 
'Extended'/'Conversational' transaction. As a result, the 'new password 
set' transient tracking in PrincipalCredentialImpl is active and is as 
if the user just set the password. This means that the 
PasswordCredential.getPassword() returns the previous password value and 
the test fails.

I am wondering if immediately after the PasswordCredential.setPassword() 
call the SSOManagetImpl.setPassword() method should invoke 
PasswordCredential.clearNewPasswordSet()? That seems like it might make 
sense in this case since we're forcing a password change, no?

Randy


---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org





Re: SSO PasswordCredential Question

Posted by Ate Douma <at...@douma.nu>.
Randy Watler wrote:
> Ate/Dennis,
> 
> In SSOManagerImpl.setPassword(), we invoke 
> PasswordCredential.setPassword(xxx, false) from 
> TestSSOManager.testCredentials() and then requery the password later in 
> the test to see if it has changed.
> 
> This works fine with OBJ, but with JPA I get the same PasswordCredential 
> instance back on the requery because it is in an 
> 'Extended'/'Conversational' transaction. As a result, the 'new password 
> set' transient tracking in PrincipalCredentialImpl is active and is as 
> if the user just set the password. This means that the 
> PasswordCredential.getPassword() returns the previous password value and 
> the test fails.
> 
> I am wondering if immediately after the PasswordCredential.setPassword() 
> call the SSOManagetImpl.setPassword() method should invoke 
> PasswordCredential.clearNewPasswordSet()? That seems like it might make 
> sense in this case since we're forcing a password change, no?
For this test that might work, but it can "break" the (generic, e.g. not SSO related) logic in for instance the 
UserPasswordCredentialPolicyManager and/or specific PasswordCredentialInterceptors.
By calling clearNewPasswordSet, the internal state (isNewPasswordSet()) is cleared as well, which might (and is!) used to determine if 
something changed on the PasswordCredential.

Now, for SSO this might be less important, at least how it *currently* is used/implemented, but that doesn't mean someone else might want to 
build upon this and expect to be able to rely on the PasswordCredential API like isNewPasswordSet() for proper operation.

As I understand this issue really comes from our Extended/Conversational JPA transaction management.
That is definitely an important feature performance wise so I'm not questioning it.
But to "simulate" the proper (user) interaction with this test-case (and possibly others too), shouldn't we then "play" multiple (JPA) 
requests/transactions then as well? That would solve this issue too AFAIK, without need for "manipulating" the API.

Ate

> 
> Randy
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
> For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org