You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shiro.apache.org by Les Hazlewood <lh...@apache.org> on 2008/12/23 19:13:45 UTC

Subject access outside of a web environment

This is a long email, but very core to JSecurity's functionality - please do
read it in its entirety.  It has wide-reaching implications ;)

A question asked by Tamas on the user list surfaced the question of how to
access a Subject outside of a web environment.

Of course there is SecurityManager.getSubject(), which should work fine.
But digging into the code, one realizes to support this method outside of a
web environment, the end-user would have to subclass the SecurityManager
implementation and override the bind(...) implementation to place the
subject identity data somewhere it could be retrieved later to reconstitute
the Subject instance.  This is certainly less than ideal (subclassing core
JSecurity components - blech).

I've actually thought about this a bit myself a long time ago when coding
the web environment support in the form of the DefaultWebSecurityManager - I
never really liked how Subject binding/acquisition was very specific to
either SecurityManager implementaiton - I wanted it to be cleaner in some
way.

So in that light, I propose that we add two new things:

1.  A SubjectAccessor (or anything that might be better named) interface,
with two methods:

bind(Subject subject) : void
acquire( Object initData ) : Subject

An instance of this interface can be injected into the
DefaultSecurityManager implementation with, of course, a sensible default
being provided automatically.  The DefaultWebSecurityManager would
initialize a different default for binding and acquiring the Subject based
on the HttpServletRequest.

This would also make it easy to support PortletRequest and Restlet
environments - just use a different SubjectAccessor implementation.

This is reminiscent of the SecurityContextBinder that was in JSecurity in
the older < 0.2 days.  Seems like now we have a good reason to bring back
that concept.

2.  A SecurityManager.getSubject( Object initData ) : Subject method

The current SecurityManager.getSubject() implementation expects that the
'initData' can be acquired in some known way from the currently executing
thread or perhaps static memory - not ideal.  The new approach would
delegate to the SubjectAccessor instance.

This additional method would also clean up some of our web and ThreadContext
related code.  We could do things like this in the JSecurityFilter or other
similar implementations for Portlet and Restlet support:

securityManager.getSubject( httpServletRequest ); //underlying
SubjectAccessor impl would be an HttpSubjectAccessor
securityManager.getSubject( portletRequest ); //underlying SubjectAccessor
impl would be a PortletSubjectAccessor
securityManager.getSubject( restletRequest ); //etc, etc.

Ultimately these changes would enabled JSecurity deployments in any custom
manner based on an injected SubjectAccessor.  StaticMemorySubjectAccessor,
FileSubjectAccessor, CacheSubjectAccessor, etc, etc.

What do you guys think?

- Les

Re: Subject access outside of a web environment

Posted by cgabbadon <cg...@informant-tech.com>.
Hi Les,

I think that exposing those two methods works just fine.  I think it makes
sense since they are already there and it obviously wouldn't be invasive or
anything to expose them now.  Last night I actually made the
getSubjectBySessionId a public method for my project, and it worked just as
I needed it to.  No objections on this side :-).

Craig


Les Hazlewood-2 wrote:
> 
> I thought about this a bit today, and I think the following on the
> SecurityManager interface (and then also SecurityUtils) would be suitable:
> 
> SecurityManager#getSubjectBySessionId( Serializable sessionId );
> SecurityManager#getSubject(PrincipalCollection principals);
> 
> Both methods would help framework developers - the first is useful in
> remoting/SSO scenarios, the 2nd useful in daemon process calls when you
> may
> not need to authenticate or have a session.  The 2nd call is essentially
> what happens in a 'remember me' scenario when someone first visits a
> website
> without a session - the identity is assumed, but there is no initial
> session
> and it is not authenticated.
> 
> Any objections from anyone?
> 
> The interesting thing about these two methods is that they already exist
> as
> private/protected methods on the underlying DefaultSecurityManager
> implemetation - maybe the should exposed now that we have some decent use
> cases?
> 
> - Les
> 
> 

-- 
View this message in context: http://n2.nabble.com/Subject-access-outside-of-a-web-environment-tp1694632p2929020.html
Sent from the JSecurity Developer mailing list archive at Nabble.com.


Re: Subject access outside of a web environment

Posted by Les Hazlewood <lh...@apache.org>.
I thought about this a bit today, and I think the following on the
SecurityManager interface (and then also SecurityUtils) would be suitable:

SecurityManager#getSubjectBySessionId( Serializable sessionId );
SecurityManager#getSubject(PrincipalCollection principals);

Both methods would help framework developers - the first is useful in
remoting/SSO scenarios, the 2nd useful in daemon process calls when you may
not need to authenticate or have a session.  The 2nd call is essentially
what happens in a 'remember me' scenario when someone first visits a website
without a session - the identity is assumed, but there is no initial session
and it is not authenticated.

Any objections from anyone?

The interesting thing about these two methods is that they already exist as
private/protected methods on the underlying DefaultSecurityManager
implemetation - maybe the should exposed now that we have some decent use
cases?

- Les

On Sun, May 17, 2009 at 3:45 PM, Les Hazlewood <lh...@apache.org>wrote:

> Hi Craig,
>
> There hasn't been much movement on this issue lately, but I started
> thumbing through issues this weekend, and this is something I think we
> should open up to end-users.  I myself have found the need for this on
> occasion, especially with my latest project - a distributed security
> environment, with multiple SecurityManagers across more than one web
> application.
>
> I'll post back to the list a little later today when I think I have a
> decent solution to allow others to comment.  If the community finds value in
> the solution, we can definitely add it.
>
> Cheers,
>
> Les
>
>
> On Sun, May 17, 2009 at 12:34 AM, cgabbadon <cg...@informant-tech.com>wrote:
>
>>
>> One thing I just noticed - I looked at the DefaultSecurityManager class
>> and
>> noticed the private method getSubjectBySessionId(Serializable sessionId)
>> that seems to be what I'm looking for.  Is there a reason why this is a
>> private method instead of a public one?
>>
>> Thanks much,
>> Craig
>>
>>
>> Les Hazlewood-2 wrote:
>> >
>> > I was playing around with potential solutions this weekend for assumed
>> > identity support as well as thinking about how to acquire a Subject
>> > without
>> > requiring a log in by the software developer and this issue:
>> >
>> > https://issues.apache.org/jira/browse/JSEC-17
>> >
>> > is very much related to this thread.  It goes back to being able to
>> > acquire
>> > a Subject instance based on some initial set of data.  In SSO
>> > applications,
>> > that 'initial set of data' might be just an SSO Token (e.g. session id).
>> > In
>> > a daemon process, it could be a PrincipalCollection instance.  Or maybe
>> > its
>> > just a single principal.
>> >
>> > I think we'll need to the ability to do this - not just get the
>> 'current'
>> > subject.
>> >
>> > Might this be related to assuming an identity?  At first glance, I think
>> > it
>> > is an orthoganal issue.  I'm not sure that this:
>> >
>> > securityManager.getSubject( initData );
>> >
>> > is (or should be) semantically equivalent to this:
>> >
>> > Subject subject = securityManager.getSubject();
>> > subject.assumeIdentity( initData );
>> >
>> > Thoughts?
>> >
>> >
>>
>> --
>> View this message in context:
>> http://n2.nabble.com/Subject-access-outside-of-a-web-environment-tp1694632p2915136.html
>> Sent from the JSecurity Developer mailing list archive at Nabble.com.
>>
>>
>

Re: Subject access outside of a web environment

Posted by Les Hazlewood <lh...@apache.org>.
Hi Craig,

There hasn't been much movement on this issue lately, but I started thumbing
through issues this weekend, and this is something I think we should open up
to end-users.  I myself have found the need for this on occasion, especially
with my latest project - a distributed security environment, with multiple
SecurityManagers across more than one web application.

I'll post back to the list a little later today when I think I have a decent
solution to allow others to comment.  If the community finds value in the
solution, we can definitely add it.

Cheers,

Les

On Sun, May 17, 2009 at 12:34 AM, cgabbadon <cg...@informant-tech.com>wrote:

>
> One thing I just noticed - I looked at the DefaultSecurityManager class and
> noticed the private method getSubjectBySessionId(Serializable sessionId)
> that seems to be what I'm looking for.  Is there a reason why this is a
> private method instead of a public one?
>
> Thanks much,
> Craig
>
>
> Les Hazlewood-2 wrote:
> >
> > I was playing around with potential solutions this weekend for assumed
> > identity support as well as thinking about how to acquire a Subject
> > without
> > requiring a log in by the software developer and this issue:
> >
> > https://issues.apache.org/jira/browse/JSEC-17
> >
> > is very much related to this thread.  It goes back to being able to
> > acquire
> > a Subject instance based on some initial set of data.  In SSO
> > applications,
> > that 'initial set of data' might be just an SSO Token (e.g. session id).
> > In
> > a daemon process, it could be a PrincipalCollection instance.  Or maybe
> > its
> > just a single principal.
> >
> > I think we'll need to the ability to do this - not just get the 'current'
> > subject.
> >
> > Might this be related to assuming an identity?  At first glance, I think
> > it
> > is an orthoganal issue.  I'm not sure that this:
> >
> > securityManager.getSubject( initData );
> >
> > is (or should be) semantically equivalent to this:
> >
> > Subject subject = securityManager.getSubject();
> > subject.assumeIdentity( initData );
> >
> > Thoughts?
> >
> >
>
> --
> View this message in context:
> http://n2.nabble.com/Subject-access-outside-of-a-web-environment-tp1694632p2915136.html
> Sent from the JSecurity Developer mailing list archive at Nabble.com.
>
>

Re: Subject access outside of a web environment

Posted by cgabbadon <cg...@informant-tech.com>.
One thing I just noticed - I looked at the DefaultSecurityManager class and
noticed the private method getSubjectBySessionId(Serializable sessionId)
that seems to be what I'm looking for.  Is there a reason why this is a
private method instead of a public one?

Thanks much,
Craig


Les Hazlewood-2 wrote:
> 
> I was playing around with potential solutions this weekend for assumed
> identity support as well as thinking about how to acquire a Subject
> without
> requiring a log in by the software developer and this issue:
> 
> https://issues.apache.org/jira/browse/JSEC-17
> 
> is very much related to this thread.  It goes back to being able to
> acquire
> a Subject instance based on some initial set of data.  In SSO
> applications,
> that 'initial set of data' might be just an SSO Token (e.g. session id). 
> In
> a daemon process, it could be a PrincipalCollection instance.  Or maybe
> its
> just a single principal.
> 
> I think we'll need to the ability to do this - not just get the 'current'
> subject.
> 
> Might this be related to assuming an identity?  At first glance, I think
> it
> is an orthoganal issue.  I'm not sure that this:
> 
> securityManager.getSubject( initData );
> 
> is (or should be) semantically equivalent to this:
> 
> Subject subject = securityManager.getSubject();
> subject.assumeIdentity( initData );
> 
> Thoughts?
> 
> 

-- 
View this message in context: http://n2.nabble.com/Subject-access-outside-of-a-web-environment-tp1694632p2915136.html
Sent from the JSecurity Developer mailing list archive at Nabble.com.


Re: Subject access outside of a web environment

Posted by cgabbadon <cg...@informant-tech.com>.
Is there any update on  https://issues.apache.org/jira/browse/KI-22 this
issue ?  I am getting into the Apache Ki project and I believe I am running
into this exact issue.  Basically, it would be ideal to get a Subject using
some data, such as the session ID, as I am trying to use Ki outside of the
typical web application context.  Since getting a session/subject seems to
be tied to the thread context coming from an InetAddress, I can't get the
proper subject.

I'm a bit new to Apache Ki, so forgive me if I am missing anything obvious. 
It's a great project based on my experience so far.  What I'm trying to do
is implement something similar to 
http://blogs.sun.com/indira/entry/rest_based_identity_services_in OpenSSO's
REST interface .  So basically, I would like to have a dedicated Apache Ki
powered security service application that is functioning as a simple
identity management/SSO/security service solution that other applications
can use via a REST interface or something else.

If you take a look at OpenSSO's REST interface, it uses the session id token
(returned from a successful authentication request) in a similar way.  I'm
not saying this is exactly how it should be done, of course - just pointing
it out.

Any suggestions?

Thanks much,

Craig


Les Hazlewood-2 wrote:
> 
> I was playing around with potential solutions this weekend for assumed
> identity support as well as thinking about how to acquire a Subject
> without
> requiring a log in by the software developer and this issue:
> 
> https://issues.apache.org/jira/browse/JSEC-17
> 
> is very much related to this thread.  It goes back to being able to
> acquire
> a Subject instance based on some initial set of data.  In SSO
> applications,
> that 'initial set of data' might be just an SSO Token (e.g. session id). 
> In
> a daemon process, it could be a PrincipalCollection instance.  Or maybe
> its
> just a single principal.
> 
> I think we'll need to the ability to do this - not just get the 'current'
> subject.
> 
> Might this be related to assuming an identity?  At first glance, I think
> it
> is an orthoganal issue.  I'm not sure that this:
> 
> securityManager.getSubject( initData );
> 
> is (or should be) semantically equivalent to this:
> 
> Subject subject = securityManager.getSubject();
> subject.assumeIdentity( initData );
> 
> Thoughts?
> 
> 

-- 
View this message in context: http://n2.nabble.com/Subject-access-outside-of-a-web-environment-tp1694632p2914755.html
Sent from the JSecurity Developer mailing list archive at Nabble.com.

Re: Subject access outside of a web environment

Posted by Les Hazlewood <lh...@apache.org>.
I was playing around with potential solutions this weekend for assumed
identity support as well as thinking about how to acquire a Subject without
requiring a log in by the software developer and this issue:

https://issues.apache.org/jira/browse/JSEC-17

is very much related to this thread.  It goes back to being able to acquire
a Subject instance based on some initial set of data.  In SSO applications,
that 'initial set of data' might be just an SSO Token (e.g. session id).  In
a daemon process, it could be a PrincipalCollection instance.  Or maybe its
just a single principal.

I think we'll need to the ability to do this - not just get the 'current'
subject.

Might this be related to assuming an identity?  At first glance, I think it
is an orthoganal issue.  I'm not sure that this:

securityManager.getSubject( initData );

is (or should be) semantically equivalent to this:

Subject subject = securityManager.getSubject();
subject.assumeIdentity( initData );

Thoughts?

On Wed, Dec 31, 2008 at 2:09 PM, Jeremy Haile <jh...@fastmail.fm> wrote:

> Yeah - in my mind the web-specific portion of the subject binding is
> actually the filter (who binds it to the thread local).  But there are lots
> of cases where the thread local stuff is useful (offline clients, daemon
> threads, and yes, web clients)  But I'm open to better ideas for doing this
> that make it more cross platform.  No matter which solution we do, it will
> be easy for the end user to access, so it's really a behind-the-scenes
> question for the most part.
>
>
>
> On Dec 31, 2008, at 12:49 PM, Les Hazlewood wrote:
>
>  On Wed, Dec 31, 2008 at 10:40 AM, Jeremy Haile <jh...@fastmail.fm>
>> wrote:
>>
>>>
>>> This may even eliminate the need entirely for a Thread-bound
>>> ServletRequest
>>>
>>>> and ServletResponse.  They were originally bound to the thread
>>>> specifically
>>>> to aid in Subject construction.  But I'd have to see whether or not a
>>>> thread-bound request/response is used in other ways before we can
>>>> definitively say binding is not necessary anymore.
>>>>
>>>>
>>> Not totally accurate in my opinion - the ThreadLocal is used so that we
>>> can
>>> access the subject anywhere without having to get access to JSecurity
>>> objects, such as the SecurityManager.  This to me implies one of two
>>> things
>>> a) you're proposing we store the Subject in the session or b) the
>>> security
>>> manager is pulling stuff out of the session and constructing a subject
>>> every
>>> time you ask for it.
>>>
>>
>>
>> I didnt' say anything about how the Subject is stored/accessed :).  I was
>> talking about a "Thread-bound ServletRequest
>> and ServletResponse".   But, after thinking about this, and based on your
>> reply, then maybe we need to still do that in a web environment so the
>> WebAccessor has something to pull from.
>>
>> Consider this alternate implementation of JSecurityFilter's
>> doFilterInternal
>> method.  Hopefully it will illustrate my thoughts:
>>
>> HttpServletRequest request = (HttpServletRequest) servletRequest;
>> HttpServletResponse response = (HttpServletResponse) servletResponse;
>>
>> //here is where we bound the InetAddress - maybe not necessary anymore
>>
>> //construct JSecurityHttpServletRequest/JSecurityHttpServletResponse same
>> as
>> in
>> //existing implementation
>>
>> //here is where we called WebUtils.bind(request)/.bind(response) - maybe
>> not
>> necessary anymore.
>>
>> Subject subject = getSecurityManager().getSubject( new HttpPair(request,
>> response) );
>> ThreadContext.bind(subject);
>> ThreadContext.bind(getSecurityManager());
>>
>> FilterChain chain = getConfiguration().getChain(request, response,
>> origChain);
>>
>> //rest of the implementation stays the same...
>>
>> Again, I don't know if this is the way it should work, its just an idea.
>> Maybe
>>
>> getSubject( new HttpPair(request, response) );
>>
>> is never called.  Maybe the request and the response ARE bound to the
>> thread, and the WebAccessor implementation knows to pull them off of the
>> thread when building the subject upon the very first request to
>> securityManager.getSubject().
>>
>> Maybe that's the cleanest way to go - I dunno yet ;)
>>
>> Automatically assuming a Thread-based model causes problems that could be
>>
>>> easily mitigated by this approach (for example, in a daemon environment,
>>>> when the thread executing isn't the same as a user request).  Lots of
>>>> flexibility there.
>>>>
>>>>
>>> Well - there are ways to support a thread-based model, even for daemon
>>> threads.  And I think daemon threads are even harder to support by
>>> assuming
>>> a request/response based model.
>>>
>>
>>
>> I'm not assuming any model - that's up to the Accessor implementation.
>>  One
>> implementation could use the ThreadContext.  Another can use Http
>> request/response pairs.  Another can pull it from a file if it is a
>> desktop
>> app.  Sure the daemon-compatible implementation can use the ThreadContext
>> -
>> I'm just saying that the SecurityManager doesn't need to know that - it is
>> up to the Accessor implementation.
>>
>> But, let's say we leave the Accessor out of it.  We'll probably need
>> securityManager.getSubject( initData) just to suport
>> runAs/assumedIdentity,
>> where 'initData' is the identiy being assumed...
>>
>
>

Re: Subject access outside of a web environment

Posted by Jeremy Haile <jh...@fastmail.fm>.
Yeah - in my mind the web-specific portion of the subject binding is  
actually the filter (who binds it to the thread local).  But there are  
lots of cases where the thread local stuff is useful (offline clients,  
daemon threads, and yes, web clients)  But I'm open to better ideas  
for doing this that make it more cross platform.  No matter which  
solution we do, it will be easy for the end user to access, so it's  
really a behind-the-scenes question for the most part.


On Dec 31, 2008, at 12:49 PM, Les Hazlewood wrote:

> On Wed, Dec 31, 2008 at 10:40 AM, Jeremy Haile <jh...@fastmail.fm>  
> wrote:
>>
>> This may even eliminate the need entirely for a Thread-bound  
>> ServletRequest
>>> and ServletResponse.  They were originally bound to the thread
>>> specifically
>>> to aid in Subject construction.  But I'd have to see whether or  
>>> not a
>>> thread-bound request/response is used in other ways before we can
>>> definitively say binding is not necessary anymore.
>>>
>>
>> Not totally accurate in my opinion - the ThreadLocal is used so  
>> that we can
>> access the subject anywhere without having to get access to JSecurity
>> objects, such as the SecurityManager.  This to me implies one of  
>> two things
>> a) you're proposing we store the Subject in the session or b) the  
>> security
>> manager is pulling stuff out of the session and constructing a  
>> subject every
>> time you ask for it.
>
>
> I didnt' say anything about how the Subject is stored/accessed :).   
> I was
> talking about a "Thread-bound ServletRequest
> and ServletResponse".   But, after thinking about this, and based on  
> your
> reply, then maybe we need to still do that in a web environment so the
> WebAccessor has something to pull from.
>
> Consider this alternate implementation of JSecurityFilter's  
> doFilterInternal
> method.  Hopefully it will illustrate my thoughts:
>
> HttpServletRequest request = (HttpServletRequest) servletRequest;
> HttpServletResponse response = (HttpServletResponse) servletResponse;
>
> //here is where we bound the InetAddress - maybe not necessary anymore
>
> //construct JSecurityHttpServletRequest/JSecurityHttpServletResponse  
> same as
> in
> //existing implementation
>
> //here is where we called WebUtils.bind(request)/.bind(response) -  
> maybe not
> necessary anymore.
>
> Subject subject = getSecurityManager().getSubject( new  
> HttpPair(request,
> response) );
> ThreadContext.bind(subject);
> ThreadContext.bind(getSecurityManager());
>
> FilterChain chain = getConfiguration().getChain(request, response,
> origChain);
>
> //rest of the implementation stays the same...
>
> Again, I don't know if this is the way it should work, its just an  
> idea.
> Maybe
>
> getSubject( new HttpPair(request, response) );
>
> is never called.  Maybe the request and the response ARE bound to the
> thread, and the WebAccessor implementation knows to pull them off of  
> the
> thread when building the subject upon the very first request to
> securityManager.getSubject().
>
> Maybe that's the cleanest way to go - I dunno yet ;)
>
> Automatically assuming a Thread-based model causes problems that  
> could be
>>> easily mitigated by this approach (for example, in a daemon  
>>> environment,
>>> when the thread executing isn't the same as a user request).  Lots  
>>> of
>>> flexibility there.
>>>
>>
>> Well - there are ways to support a thread-based model, even for  
>> daemon
>> threads.  And I think daemon threads are even harder to support by  
>> assuming
>> a request/response based model.
>
>
> I'm not assuming any model - that's up to the Accessor  
> implementation.  One
> implementation could use the ThreadContext.  Another can use Http
> request/response pairs.  Another can pull it from a file if it is a  
> desktop
> app.  Sure the daemon-compatible implementation can use the  
> ThreadContext -
> I'm just saying that the SecurityManager doesn't need to know that -  
> it is
> up to the Accessor implementation.
>
> But, let's say we leave the Accessor out of it.  We'll probably need
> securityManager.getSubject( initData) just to suport runAs/ 
> assumedIdentity,
> where 'initData' is the identiy being assumed...


Re: Subject access outside of a web environment

Posted by Les Hazlewood <lh...@apache.org>.
On Wed, Dec 31, 2008 at 10:40 AM, Jeremy Haile <jh...@fastmail.fm> wrote:
>
> This may even eliminate the need entirely for a Thread-bound ServletRequest
>> and ServletResponse.  They were originally bound to the thread
>> specifically
>> to aid in Subject construction.  But I'd have to see whether or not a
>> thread-bound request/response is used in other ways before we can
>> definitively say binding is not necessary anymore.
>>
>
> Not totally accurate in my opinion - the ThreadLocal is used so that we can
> access the subject anywhere without having to get access to JSecurity
> objects, such as the SecurityManager.  This to me implies one of two things
> a) you're proposing we store the Subject in the session or b) the security
> manager is pulling stuff out of the session and constructing a subject every
> time you ask for it.


I didnt' say anything about how the Subject is stored/accessed :).  I was
talking about a "Thread-bound ServletRequest
and ServletResponse".   But, after thinking about this, and based on your
reply, then maybe we need to still do that in a web environment so the
WebAccessor has something to pull from.

Consider this alternate implementation of JSecurityFilter's doFilterInternal
method.  Hopefully it will illustrate my thoughts:

HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

//here is where we bound the InetAddress - maybe not necessary anymore

//construct JSecurityHttpServletRequest/JSecurityHttpServletResponse same as
in
//existing implementation

//here is where we called WebUtils.bind(request)/.bind(response) - maybe not
necessary anymore.

Subject subject = getSecurityManager().getSubject( new HttpPair(request,
response) );
ThreadContext.bind(subject);
ThreadContext.bind(getSecurityManager());

FilterChain chain = getConfiguration().getChain(request, response,
origChain);

//rest of the implementation stays the same...

Again, I don't know if this is the way it should work, its just an idea.
Maybe

getSubject( new HttpPair(request, response) );

is never called.  Maybe the request and the response ARE bound to the
thread, and the WebAccessor implementation knows to pull them off of the
thread when building the subject upon the very first request to
securityManager.getSubject().

Maybe that's the cleanest way to go - I dunno yet ;)

 Automatically assuming a Thread-based model causes problems that could be
>> easily mitigated by this approach (for example, in a daemon environment,
>> when the thread executing isn't the same as a user request).  Lots of
>> flexibility there.
>>
>
> Well - there are ways to support a thread-based model, even for daemon
> threads.  And I think daemon threads are even harder to support by assuming
> a request/response based model.


I'm not assuming any model - that's up to the Accessor implementation.  One
implementation could use the ThreadContext.  Another can use Http
request/response pairs.  Another can pull it from a file if it is a desktop
app.  Sure the daemon-compatible implementation can use the ThreadContext -
I'm just saying that the SecurityManager doesn't need to know that - it is
up to the Accessor implementation.

But, let's say we leave the Accessor out of it.  We'll probably need
securityManager.getSubject( initData) just to suport runAs/assumedIdentity,
where 'initData' is the identiy being assumed...

Re: Subject access outside of a web environment

Posted by Jeremy Haile <jh...@fastmail.fm>.
Wow - Les, you sure know how to write long-winded responses =)

On Dec 31, 2008, at 10:15 AM, Les Hazlewood wrote:

> On Tue, Dec 30, 2008 at 3:34 PM, Jeremy Haile <jh...@fastmail.fm>  
> wrote:
>
>> OK - I'll try to keep my feedback brief here.  I believe that most  
>> users of
>> JSecurity are and will always be web application developers.  So  
>> although I
>> want to make it easy to use JSecurity in a non-web environment, I  
>> don't want
>> to sacrifice the ease-of-use in web environments to do so.
>
>
> I agree.  But if the architecture is sound, it shouldn't matter.  I'm
> currently using JSecurity in a complicated web-based product where  
> some
> shortcomings of the current architecture surface rather quickly:

I agree.  My point is that the backend architecture can be complex (if  
necessary), but the user experience shouldn't suffer.  And we should  
focus foremost on the startup cost and user experience of simple web  
apps, since that's our biggest audience.  If through good architecture  
we can make it simple to use, yet robust and powerful for edge-case  
scenarios - that's the ideal.

As with any system, we should still strive for simplicity - even in  
the backend, since it leads to more understandable, maintainable, and  
SECURE code.

> I see the need for a Remote/Client SecurityManager implementation  
> that can
> reside in 3rd party processes (e.g. my current web environment, or  
> maybe an
> applet, or standalone application) that remote back to a 'primary'  
> JSecurity
> DefaultSecurityManager.  This would be in addition to the already  
> nice web
> infrastructure.  It would certainly make a federated application  
> cluster
> built on top of JSecurity much nicer.  But in any case, these things  
> surface
> the need for architectural improvements that would benefit many
> environments.

Yeah - I definitely think solving this problem in the general case is  
something that needs some more discussion, and perhaps some UML  
diagrams before implementing.  I think it's valid to ask whether this  
should be very transparent, or whether it should be more explicit in  
the code/architecture.

> The Spring Remoting support needs to be cleaned up quite a bit too -  
> instead
> of relying on a session id system property, we need to acquire the  
> subject
> in another way (SecurityUtils?) and acquire the session id that  
> way.  I had
> to do more subclassing there, as well as alter the server-side
> InvocationExecutor. More fun...

Yeah, the Spring Remoting support is pretty basic now.   It'd be good  
to think it through along with other web service remoting support.

> Cool.  I think we'll also need to create the notion of a  
> SubjectFactory
> again.<snip/>
> Based on my experiences above, I'm quickly becoming an advocate that  
> people
> should not have to subclass the SecurityManager in any environment  
> unless
> something _really_ weird is being done.  A SubjectFactory in  
> addition to a
> SubjectAccesor I think would round out the things necessary to  
> realize this
> architectural philosophy.

I like the idea of using factory pattern, accessor pattern, etc. as  
long as this is hidden from the user in the common use cases.

> DefaultWebSecurityManager() {
>    setSubjectAccessor( new HttpContainerSubjectAccessor() );
> }

Small note - but again - currently we use ThreadLocals to store it in  
a web environment.  I see this as a separate change that should be  
discussed separately (and I'll discuss more in response to your  
comments below)

> This may even eliminate the need entirely for a Thread-bound  
> ServletRequest
> and ServletResponse.  They were originally bound to the thread  
> specifically
> to aid in Subject construction.  But I'd have to see whether or not a
> thread-bound request/response is used in other ways before we can
> definitively say binding is not necessary anymore.

Not totally accurate in my opinion - the ThreadLocal is used so that  
we can access the subject anywhere without having to get access to  
JSecurity objects, such as the SecurityManager.  This to me implies  
one of two things a) you're proposing we store the Subject in the  
session or b) the security manager is pulling stuff out of the session  
and constructing a subject every time you ask for it.

I'm not sure that either of those are desirable, but I'm open to  
discussing it further.

> Automatically assuming a Thread-based model causes problems that  
> could be
> easily mitigated by this approach (for example, in a daemon  
> environment,
> when the thread executing isn't the same as a user request).  Lots of
> flexibility there.

Well - there are ways to support a thread-based model, even for daemon  
threads.  And I think daemon threads are even harder to support by  
assuming a request/response based model.


Re: Subject access outside of a web environment

Posted by Les Hazlewood <lh...@apache.org>.
On Tue, Dec 30, 2008 at 3:34 PM, Jeremy Haile <jh...@fastmail.fm> wrote:

> OK - I'll try to keep my feedback brief here.  I believe that most users of
> JSecurity are and will always be web application developers.  So although I
> want to make it easy to use JSecurity in a non-web environment, I don't want
> to sacrifice the ease-of-use in web environments to do so.


I agree.  But if the architecture is sound, it shouldn't matter.  I'm
currently using JSecurity in a complicated web-based product where some
shortcomings of the current architecture surface rather quickly:

We have a distributed architecture - the application is deployed in two
different tiers of physical machines.  The web code runs in one set of
machines and the business tier code runs on another set of machines.
Although obviously not ideal and I hate it, it must be done this way as the
company's internal security team has an incredible distrust of web
applications - they force a firewall between the two sets of machines.  We
use Spring remoting between the two tiers.

So, there is one JSecurity SecurityManager in the web tier that handles
cookies and such, but this is (aside from specific web/cookie support) a
proxy to the business-tier JSecurity security manager.  The business-tier
one manages actual Session instances and their lifecycle.

Setting this up _should_ have been simple.  But because of the current
architecture, I couldn't just use the DefaultWebSecurityManager on the web
tier and make it proxy to the business-tier DefaultSecurityManager.  I had
to subclass DWSM, re-implement a few methods that explicitly called
super.doSomething, proxy many more methods to an injected remote proxy of
the business-tier SM and more junk.  I'm not finished with this process
either, and its causing me a lot of problems.

Most of this hardship is related to Session Management.  Because
SecurityManager doesn't extend the SessionManager interface (it extends
SessionFactory instead), I couldn't just easily proxy the SessionManager
methods to the back-end SecurityManager instance.  I'm jumping through a lot
of unnecessary hoops because of the architecture.  Needless to say, I want
to clean this up significanty.

I see the need for a Remote/Client SecurityManager implementation that can
reside in 3rd party processes (e.g. my current web environment, or maybe an
applet, or standalone application) that remote back to a 'primary' JSecurity
DefaultSecurityManager.  This would be in addition to the already nice web
infrastructure.  It would certainly make a federated application cluster
built on top of JSecurity much nicer.  But in any case, these things surface
the need for architectural improvements that would benefit many
environments.

The Spring Remoting support needs to be cleaned up quite a bit too - instead
of relying on a session id system property, we need to acquire the subject
in another way (SecurityUtils?) and acquire the session id that way.  I had
to do more subclassing there, as well as alter the server-side
InvocationExecutor. More fun...

Anyway, lots to do to support web, non-web, and hybrid solutions.  But it
shouldn't affect web-only solutions in any way though - will make them a
little cleaner in fact.

1) I like the idea of using a SubjectAccessor and having the SecurityManager
> delegate to that.


Cool.  I think we'll also need to create the notion of a SubjectFactory
again.  It'd be nice for people to inject one of those into the
SecurityManager instance instead of having to subclass the SecurityManager.


Based on my experiences above, I'm quickly becoming an advocate that people
should not have to subclass the SecurityManager in any environment unless
something _really_ weird is being done.  A SubjectFactory in addition to a
SubjectAccesor I think would round out the things necessary to realize this
architectural philosophy.

2) I think you still run into the problem of where to get the appropriate
> accessor from, how to configure it, etc.  I presume the default would be web
> based?  Or we could do an SLF4J approach and make the default depend on what
> modules are included in the classpath. (i.e. if you include the "web" module
> that one is used, if you include the "nonweb?" one that's used)


The default would probably be thread based (DefaultSecurityManager), but the
DefaultWebSecurityManager would have as its default a web based one, sure.
In any case, anyone could override either just by injecting their own
implementation.  Pretty clean.

For example (default implementations):

DefaultSecurityManager() {
    setSubjectAccessor( new ThreadContextSubjectAccessor() );
}

DefaultWebSecurityManager() {
    setSubjectAccessor( new HttpContainerSubjectAccessor() );
}

3) I'm not sure I understand why initData is used.  In our current web
> implementation we use ThreadLocal variables to store the subject - wouldn't
> we just continue doing that?  Shouldn't the accessor internally contain any
> init data it needs?


This is because the data required to construct a Subject differ across
environments.  In one environment (a non web based one), it could be just a
session id.  In a web-based environment that initData object could be (new
HttpServletPair(request, response)).

The implementation could determine what that 'initData' object could be.  In
the web support, the JSecurityFilter would be changed to construct an
instance of HttpServletPair and inject that.  A Portlet-specific
implementation could receive a PortletPair.

This may even eliminate the need entirely for a Thread-bound ServletRequest
and ServletResponse.  They were originally bound to the thread specifically
to aid in Subject construction.  But I'd have to see whether or not a
thread-bound request/response is used in other ways before we can
definitively say binding is not necessary anymore.

Automatically assuming a Thread-based model causes problems that could be
easily mitigated by this approach (for example, in a daemon environment,
when the thread executing isn't the same as a user request).  Lots of
flexibility there.

4) I assume we'd still have some sort of static methods available for web
> contexts that would allow easy access to the subject via a threadlocal?
> (e.g. SecurityUtils.getSubject() )


Absolutely, that wouldn't go away.

These changes wouldn't affect the web functionality in any way - it just
makes other environments much easier to use as well.

Re: Subject access outside of a web environment

Posted by Jeremy Haile <jh...@fastmail.fm>.
OK - I'll try to keep my feedback brief here.  I believe that most  
users of JSecurity are and will always be web application developers.   
So although I want to make it easy to use JSecurity in a non-web  
environment, I don't want to sacrifice the ease-of-use in web  
environments to do so.

1) I like the idea of using a SubjectAccessor and having the  
SecurityManager delegate to that.

2) I think you still run into the problem of where to get the  
appropriate accessor from, how to configure it, etc.  I presume the  
default would be web based?  Or we could do an SLF4J approach and make  
the default depend on what modules are included in the classpath.  
(i.e. if you include the "web" module that one is used, if you include  
the "nonweb?" one that's used)

3) I'm not sure I understand why initData is used.  In our current web  
implementation we use ThreadLocal variables to store the subject -  
wouldn't we just continue doing that?  Shouldn't the accessor  
internally contain any init data it needs?

4) I assume we'd still have some sort of static methods available for  
web contexts that would allow easy access to the subject via a  
threadlocal? (e.g. SecurityUtils.getSubject() )




On Dec 23, 2008, at 1:13 PM, Les Hazlewood wrote:

> This is a long email, but very core to JSecurity's functionality -  
> please do
> read it in its entirety.  It has wide-reaching implications ;)
>
> A question asked by Tamas on the user list surfaced the question of  
> how to
> access a Subject outside of a web environment.
>
> Of course there is SecurityManager.getSubject(), which should work  
> fine.
> But digging into the code, one realizes to support this method  
> outside of a
> web environment, the end-user would have to subclass the  
> SecurityManager
> implementation and override the bind(...) implementation to place the
> subject identity data somewhere it could be retrieved later to  
> reconstitute
> the Subject instance.  This is certainly less than ideal  
> (subclassing core
> JSecurity components - blech).
>
> I've actually thought about this a bit myself a long time ago when  
> coding
> the web environment support in the form of the  
> DefaultWebSecurityManager - I
> never really liked how Subject binding/acquisition was very specific  
> to
> either SecurityManager implementaiton - I wanted it to be cleaner in  
> some
> way.
>
> So in that light, I propose that we add two new things:
>
> 1.  A SubjectAccessor (or anything that might be better named)  
> interface,
> with two methods:
>
> bind(Subject subject) : void
> acquire( Object initData ) : Subject
>
> An instance of this interface can be injected into the
> DefaultSecurityManager implementation with, of course, a sensible  
> default
> being provided automatically.  The DefaultWebSecurityManager would
> initialize a different default for binding and acquiring the Subject  
> based
> on the HttpServletRequest.
>
> This would also make it easy to support PortletRequest and Restlet
> environments - just use a different SubjectAccessor implementation.
>
> This is reminiscent of the SecurityContextBinder that was in  
> JSecurity in
> the older < 0.2 days.  Seems like now we have a good reason to bring  
> back
> that concept.
>
> 2.  A SecurityManager.getSubject( Object initData ) : Subject method
>
> The current SecurityManager.getSubject() implementation expects that  
> the
> 'initData' can be acquired in some known way from the currently  
> executing
> thread or perhaps static memory - not ideal.  The new approach would
> delegate to the SubjectAccessor instance.
>
> This additional method would also clean up some of our web and  
> ThreadContext
> related code.  We could do things like this in the JSecurityFilter  
> or other
> similar implementations for Portlet and Restlet support:
>
> securityManager.getSubject( httpServletRequest ); //underlying
> SubjectAccessor impl would be an HttpSubjectAccessor
> securityManager.getSubject( portletRequest ); //underlying  
> SubjectAccessor
> impl would be a PortletSubjectAccessor
> securityManager.getSubject( restletRequest ); //etc, etc.
>
> Ultimately these changes would enabled JSecurity deployments in any  
> custom
> manner based on an injected SubjectAccessor.   
> StaticMemorySubjectAccessor,
> FileSubjectAccessor, CacheSubjectAccessor, etc, etc.
>
> What do you guys think?
>
> - Les