Assumed Identity/Run As Architecture

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Assumed Identity/Run As Architecture

Les Hazlewood-2
I'm kicking off this thread for continued discussion on how to implement the
AssumedIdentity/RunAs feature.

For now I'm assuming we'll put the method to assume another user's identity
directly in the existing Subject interface - no sub-interface.

Also something I was thinking about this morning was a stack might be needed
to 'remember' the assumed identities if there are multiple calls:

Subject subject = securityManager.getSubject();
subject.assumeIdentity( foo );
... some code
subject.assumeIdentity( bar );

This would allow functionality like 'su' in unix, where you could assume a
user's identity any number of times:

> # login as originalUser here

> su someUser
> ...
> su anotherUser
..
> exit
(drops you back to 'someUser' here)
> ...
> exit
(drops you back to 'originalUser' here)

This means the SecurityManager or the DelegatingSubject (or both) needs to
be aware of this stack.  I haven't quite figured out how this would work
yet, or how it would work in a RememberMe context, but I wanted to jot down
my ideas here for record and to allow any feedback.

- Les
Reply | Threaded
Open this post in threaded view
|

Re: Assumed Identity/Run As Architecture

Les Hazlewood-2
I tried to see if I could start implementing this feature today, and I
reviewed this post again.  Any feedback as to if we should store the assumed
identity in the session and be done with it?  Or should it be stack-like as
described in my original post?

For some reason I feel we should be able to support stack-like behavior.
But here's the real question:  When assuming another user's identity, what
about the other methods not entirely based on a principal?

For example, let's say I did this, as user 'bob':

Subject subject = SecurityUtils.getSubject();
//subject currently represents the 'original/owning' user, 'bob'.

//assume joe's identity:
subject.assumeIdentity("joe");

Now that we've done that, what happens should any of the following methods
be called?  We've only really talked about what happens when getPrincipal()
is called, not these:

subject.isAuthenticated()
subject.getPrincipals()
subject.getSession() / subject.getSession(false);
subject.login(...)
subject.logout();

Do these methods function based on bob's authentication status and session
Or joe's?  What if login and/or login is called?  What should be the
expected behavior?

Then the issue of the session - if a new session is created while assuming
joe's identity, any session operations in 'joes' session should also update
the timestamp of the original 'bob' session to ensure it doesn't time out so
it is still available after relinquishing the 'joe' identity.

These are some of the things to consider when choosing a 'correct' approach.

Any feedback?  Ideas?

Thanks,

Les

On Wed, Jan 14, 2009 at 9:51 AM, Les Hazlewood <[hidden email]>wrote:

> I'm kicking off this thread for continued discussion on how to implement
> the AssumedIdentity/RunAs feature.
>
> For now I'm assuming we'll put the method to assume another user's identity
> directly in the existing Subject interface - no sub-interface.
>
> Also something I was thinking about this morning was a stack might be
> needed to 'remember' the assumed identities if there are multiple calls:
>
> Subject subject = securityManager.getSubject();
> subject.assumeIdentity( foo );
> ... some code
> subject.assumeIdentity( bar );
>
> This would allow functionality like 'su' in unix, where you could assume a
> user's identity any number of times:
>
> > # login as originalUser here
>
> > su someUser
> > ...
> > su anotherUser
> ..
> > exit
> (drops you back to 'someUser' here)
> > ...
> > exit
> (drops you back to 'originalUser' here)
>
> This means the SecurityManager or the DelegatingSubject (or both) needs to
> be aware of this stack.  I haven't quite figured out how this would work
> yet, or how it would work in a RememberMe context, but I wanted to jot down
> my ideas here for record and to allow any feedback.
>
> - Les
>
Reply | Threaded
Open this post in threaded view
|

Re: Assumed Identity/Run As Architecture

Les Hazlewood-2
On second thought, maybe 'assumeIdentity' is just that - the Principal is
assumed and everything else about 'bob's Subject state (session,
authentication, etc) is retained.

The 'stack like' functionality might be cause for a separate feature in the
future, say 'switchUser' to mimic a full stack-like behavior like what I
outlined originally, if users actually desire such a feature.

Feedback is still welcome ;)

On Thu, Jan 29, 2009 at 11:48 PM, Les Hazlewood <[hidden email]>wrote:

> I tried to see if I could start implementing this feature today, and I
> reviewed this post again.  Any feedback as to if we should store the assumed
> identity in the session and be done with it?  Or should it be stack-like as
> described in my original post?
>
> For some reason I feel we should be able to support stack-like behavior.
> But here's the real question:  When assuming another user's identity, what
> about the other methods not entirely based on a principal?
>
> For example, let's say I did this, as user 'bob':
>
> Subject subject = SecurityUtils.getSubject();
> //subject currently represents the 'original/owning' user, 'bob'.
>
> //assume joe's identity:
> subject.assumeIdentity("joe");
>
> Now that we've done that, what happens should any of the following methods
> be called?  We've only really talked about what happens when getPrincipal()
> is called, not these:
>
> subject.isAuthenticated()
> subject.getPrincipals()
> subject.getSession() / subject.getSession(false);
> subject.login(...)
> subject.logout();
>
> Do these methods function based on bob's authentication status and session
> Or joe's?  What if login and/or login is called?  What should be the
> expected behavior?
>
> Then the issue of the session - if a new session is created while assuming
> joe's identity, any session operations in 'joes' session should also update
> the timestamp of the original 'bob' session to ensure it doesn't time out so
> it is still available after relinquishing the 'joe' identity.
>
> These are some of the things to consider when choosing a 'correct'
> approach.
>
> Any feedback?  Ideas?
>
> Thanks,
>
> Les
>
>
> On Wed, Jan 14, 2009 at 9:51 AM, Les Hazlewood <[hidden email]>wrote:
>
>> I'm kicking off this thread for continued discussion on how to implement
>> the AssumedIdentity/RunAs feature.
>>
>> For now I'm assuming we'll put the method to assume another user's
>> identity directly in the existing Subject interface - no sub-interface.
>>
>> Also something I was thinking about this morning was a stack might be
>> needed to 'remember' the assumed identities if there are multiple calls:
>>
>> Subject subject = securityManager.getSubject();
>> subject.assumeIdentity( foo );
>> ... some code
>> subject.assumeIdentity( bar );
>>
>> This would allow functionality like 'su' in unix, where you could assume a
>> user's identity any number of times:
>>
>> > # login as originalUser here
>>
>> > su someUser
>> > ...
>> > su anotherUser
>> ..
>> > exit
>> (drops you back to 'someUser' here)
>> > ...
>> > exit
>> (drops you back to 'originalUser' here)
>>
>> This means the SecurityManager or the DelegatingSubject (or both) needs to
>> be aware of this stack.  I haven't quite figured out how this would work
>> yet, or how it would work in a RememberMe context, but I wanted to jot down
>> my ideas here for record and to allow any feedback.
>>
>> - Les
>>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Assumed Identity/Run As Architecture

Daniel J. Lauk
Hi Les.

2009/1/30 Les Hazlewood <[hidden email]>:
> On second thought, maybe 'assumeIdentity' is just that - the Principal is
> assumed and everything else about 'bob's Subject state (session,
> authentication, etc) is retained.

That's what I'd suggest and what I implemented.
BTW: I never got feedback about the files i attached to JIRA (or I missed it).

>> subject.getPrincipals()

If I understood correctly, the first item in the PrincipalCollection
is the main Principal (i.e. the one used with authorization).
So, I figured, the assumed identity's principal has to be prepended to
the original PrincipalCollection.

For the other methods, I'd say, just leave them.

> The 'stack like' functionality might be cause for a separate feature in the
> future, say 'switchUser' to mimic a full stack-like behavior like what I
> outlined originally, if users actually desire such a feature.

That's what "substitute user" (Unix-ish) would be, right?
Reminding you of some previous discussion, I think this is what we
agreed on (or stopped going on discussing):

All we do is "assume the identity of another subject". We do not
"substitute the user" in their entirety.
As the difference is so subtle (to me), I'd still recommend the "act
on behalf of" naming, which IMHO makes it easier to distinguish.
But beware: I'm no English native speaker, so my perception of
"subtleties" may be completely out of balance ;-)

> Feedback is still welcome ;)

You asked for it... ;-)

Cheers,
DJ
Reply | Threaded
Open this post in threaded view
|

Re: Assumed Identity/Run As Architecture

Les Hazlewood-2
On Fri, Jan 30, 2009 at 3:05 AM, Daniel J. Lauk <[hidden email]>wrote:

> Hi Les.
>
> 2009/1/30 Les Hazlewood <[hidden email]>:
> > On second thought, maybe 'assumeIdentity' is just that - the Principal is
> > assumed and everything else about 'bob's Subject state (session,
> > authentication, etc) is retained.
>
> That's what I'd suggest and what I implemented.
> BTW: I never got feedback about the files i attached to JIRA (or I missed
> it).


Ah yes, I forgot to add that to this thread last night.  I reviewed the
files and they were along the line of what I was thinking initially - thanks
very much for contributing.  However, from what I remember late last night
(and if I'm wrong, please correct me), the files you attached didn't address
the PrincipalsCollection issue - nothing wrong with that of course, I'm just
checking for clarity.  See below...


> >> subject.getPrincipals()
>
> If I understood correctly, the first item in the PrincipalCollection
> is the main Principal (i.e. the one used with authorization).
> So, I figured, the assumed identity's principal has to be prepended to
> the original PrincipalCollection.


Storing the assumed identity in the session is perfectly fine as I
recommended originally and as your uploaded files do, but I wasn't thinking
about the PrincipalCollection at the time.  Now the question is _should_ the
assumedIdentity go in the 'owning' user's principals collection or, when
calling getPrincipals(), a new PrincipalCollection is returned that wraps
the assumed identity + the existing PrincipalCollection?

I ask because the former approach requires methods to prepend the assumed
identity to the existing PrincipalCollection instead of creating a new
instance.  Methods like MutablePrincipalCollection.set( index, realmName,
value )  or MutablePrincipalCollection.add( realmName, value) - that kind of
thing.

This might have repercussions for RememberMe:  the PrincipalCollection is
serialized and encrypted as a cookie.  If the end-user does not log out, and
they come back and RememberMe is enabled, should it also remember the
assumed identity?  That would happen if we modified the original user's
PrincipalCollection.

It would not happen though if we create a temporary instance that wraps the
assumed identity + the original Collection, and then return that temporary
instance from the getPrincipals() call during the life of the owning
session.  It would not be remembered since the assumed identity would not be
in the RememberMe cookie and when the owning user's session dies, so does
the assumedIdentity association.


> For the other methods, I'd say, just leave them.


I'm inclined to agree. It would certainly make this implementation effort
easier :)

> The 'stack like' functionality might be cause for a separate feature in
> the
> > future, say 'switchUser' to mimic a full stack-like behavior like what I
> > outlined originally, if users actually desire such a feature.
>
> That's what "substitute user" (Unix-ish) would be, right?
> Reminding you of some previous discussion, I think this is what we
> agreed on (or stopped going on discussing):


Yep, switchUser/substituteUser functionality would probably require proper
stack-like retention of state (session, authentication state, and anything
else).  I'm not sure that users even care about this either and I don't
think I'm going to worry about it unless someone asks for it ;)

All we do is "assume the identity of another subject". We do not
> "substitute the user" in their entirety.
> As the difference is so subtle (to me), I'd still recommend the "act
> on behalf of" naming, which IMHO makes it easier to distinguish.
> But beware: I'm no English native speaker, so my perception of
> "subtleties" may be completely out of balance ;-)


No disrespect of course, but I view them almost the same.  I think
'actOnBehalfOf' is a little vague as to what actually is supposed to happen,
where I think 'assumeIdentity' is a little more focused on its intentions.
Just my opinion though...

> Feedback is still welcome ;)
>
> You asked for it... ;-)
>

It is much appreciated :)  Thanks!

Regards,

Les
Reply | Threaded
Open this post in threaded view
|

Re: Assumed Identity/Run As Architecture

Daniel J. Lauk
Hi.

>> BTW: I never got feedback about the files i attached to JIRA (or I missed
>> it).
>
> Ah yes, I forgot to add that to this thread last night.  I reviewed the
> files and they were along the line of what I was thinking initially - thanks
> very much for contributing.  However, from what I remember late last night
> (and if I'm wrong, please correct me), the files you attached didn't address
> the PrincipalsCollection issue - nothing wrong with that of course, I'm just
> checking for clarity.  See below...

I did address the issue. But I'm not sure, if I did it right.
That's why there are @todo lines in the javadoc comments to
AssumeIdentitySubject.getPrincipals(). :-)


> Storing the assumed identity in the session is perfectly fine as I
> recommended originally and as your uploaded files do, but I wasn't thinking
> about the PrincipalCollection at the time.  Now the question is _should_ the
> assumedIdentity go in the 'owning' user's principals collection or, when
> calling getPrincipals(), a new PrincipalCollection is returned that wraps
> the assumed identity + the existing PrincipalCollection?
>
> I ask because the former approach requires methods to prepend the assumed
> identity to the existing PrincipalCollection instead of creating a new
> instance.  Methods like MutablePrincipalCollection.set( index, realmName,
> value )  or MutablePrincipalCollection.add( realmName, value) - that kind of
> thing.

----8<--------8<--------8<--------8<--------8<--------8<----

> This might have repercussions for RememberMe:  the PrincipalCollection is
> serialized and encrypted as a cookie.  If the end-user does not log out, and
> they come back and RememberMe is enabled, should it also remember the
> assumed identity?  That would happen if we modified the original user's
> PrincipalCollection.
>
> It would not happen though if we create a temporary instance that wraps the
> assumed identity + the original Collection, and then return that temporary
> instance from the getPrincipals() call during the life of the owning
> session.  It would not be remembered since the assumed identity would not be
> in the RememberMe cookie and when the owning user's session dies, so does
> the assumedIdentity association.


I thought, that's what I did. But I am not sure, if I did it right as
I face issues with relinquishing (funny word...) the assumed identity.
(I decided to go on with other issues first, as logging out does the
trick).

<code>
        public PrincipalCollection getPrincipals() {
                if (getAssumedPrincipal() == null) return decoratedSubject.getPrincipals();

                PrincipalCollection authPrincipals = decoratedSubject.getPrincipals();
                String realmName = authPrincipals.getRealmNames().iterator().next();
                SimplePrincipalCollection spc = new SimplePrincipalCollection();
                spc.add(getAssumedPrincipal(), realmName);
                spc.addAll(authPrincipals);
                return spc;
        }
</code>



>> For the other methods, I'd say, just leave them.
>
>
> I'm inclined to agree. It would certainly make this implementation effort
> easier :)
----8<--------8<--------8<--------8<--------8<--------8<----
> Yep, switchUser/substituteUser functionality would probably require proper
> stack-like retention of state (session, authentication state, and anything
> else).  I'm not sure that users even care about this either and I don't
> think I'm going to worry about it unless someone asks for it ;)

I daresay that there are other items to be taken care of for the 1.0 release.
I assume that the most important use case is for
supporters/administrators to help a user out, and this solution solves
that.



>> As the difference is so subtle (to me), I'd still recommend the "act
>> on behalf of" naming, which IMHO makes it easier to distinguish.
>> But beware: I'm no English native speaker, so my perception of
>> "subtleties" may be completely out of balance ;-)
>
>
> No disrespect of course, but I view them almost the same.  I think
> 'actOnBehalfOf' is a little vague as to what actually is supposed to happen,
> where I think 'assumeIdentity' is a little more focused on its intentions.
> Just my opinion though...

Thanks for reflecting on it. As I'm currently reading about and
working on identity management, it could well be that I'm just over
sensitive. The terminology has so many facets, that experts disagree
to a certain amount. Even the people in our small team working on the
topic have (slightly) different views of the meaning of "identity".

The notion I especially like about "actOnBehalfOf" is that there are
two entities involved (e.g. the support guy resets the password on
behalf of the user).
A final idea would be: ("loginAs" or rather) "authenticateAs"
By the way: What was the outcome of the poll? Which naming did the
others prefer?

But after all: "What's in a name?"
As long as the API documentation precisely describes what is going on,
the subtle differences make no big deal, I guess.

Cheers,
DJ