The problem with Subject.doAs is, it calls
AccessController.doPrivileged, which after it uses the DomainCombiner,
set's it null, in other words, while your new ProtectionDomain's now
contain the Subject's Principals, the new AccessControlContext no longer
contains the domain combiner.
In Java 6, they added some new methods to AccessController that
preserves the DomainCombiner, but Subject.doAs doesn't call them.
This is why net.jini.security.Security contain's doPrivileged methods,
to preserve the DomainCombiner.
To work around it, you could make a Principal implementation that holds
credentials, or the Subject, then you could use your own domain combiner
to retrieve them.
Maybe there's a better solution, anyone have any ideas?
Cheers,
Peter.
Gregg Wonderly wrote:
On 8/16/2011 1:10 AM, Peter Firmstone wrote:
Gregg,
I'm wondering if you might like to donate the code to River, perhaps
under an
new Jira?
Much of this code is visible on java.net under the authlib and pastion
projects. I may have more up to date versions that I have not synced
out there yet. The server side invocation handler with subject
extraction, in particular, may not be a working version. After seeing
your followup with the steps to get the Subject conveyed over the
endpoint path, I was reminded that I may not have finished getting
that completed, and might have just roughed that out in testing and
moved to the factory login mechanism because it helped manage some
other session life-cycle issues as well.
Gregg Wonderly
Gregg Wonderly wrote:
On 8/11/2011 9:34 PM, Peter Firmstone wrote:
Gregg Wonderly wrote:
I've done this a couple of different ways. I do have a server side
invocation
handler that can extract a Principal from the calling context to
find an
identity, and then use JAAS to login to check your login credentials.
Interesting, so you get the current AccessControlContext, because
the field
context is private, you must have a DomainCombiner? Then you'd need
to create a
new AccessControlContext, with your DomainCombiner implementation,
call
doPrivileged (which causes the combiner to be called). With the
DomainCombiner,
you retrieve the assignedDomain's, the call getPrincipal's on all
ProtectionDomains, then find a common subset of Principals that all
ProtectionDomain's have?
Then what?
No, I just do as Greg described with inspecting the
AccessController.getContext() value for the "credentials", tuck
those into a
JAAS Callback handler, create a LoginContext with the appropriate
context
name, call LoginContext.login(), and if that succeeds, make the
method call
with Sobject.doAs(). This does two things. One, it lets me use
AccessController/checkPermission, if I want to in server code. But
second, it
performs the authentication on each call in. The overhead of that
check, for
me, is the issue to decide on. If it seems too much, then use the
other method
I described by authenticating once and returning a service proxy
that has the
authorization plugged in that is appropriate for that identity.
My JNI interface to PAM allows me to extract/create user and group
Principals,
put those into a Subject and then doAs() from there. This is what
you would
use in a complex application that needs absolute authentication
control when a
credential change should disallow access instantly.
I predominately have no worries about "stolen remote objects" or
revoked
access rights. And so single authentication is fine with me, and I
use a
factory interface with a single method that I pass
identity/credentials to
with remote call.
I'm guessing you do this over TCPEndpoint's? This is for private
networks?
I do it over SSL mostly to hide the credentials that are in flight.
This is
not great because it is in no way using single sign on services.
But, its what
works. My customers use either a single "tech" sign on, or have PAM
support
for whatever corporate authentication system they use. They don't ask
questions about me actually having passwords in my code and passing
them
around. I keep that information tightly controlled in the code, and
don't log
it or otherwise expose it.
This is where I feel JAAS falls down. It should do all of this for
us! We
should be able to call a factory method that returns an
authenticated Subject.
The problem is really Applets. Because they exist, and mobile code
allows
"unknown" things to happen, the JAAS developers appear to have been
put off by
the fact that if Java code could get "authenticated" Subjects, ready
for use,
that Applets could steal into a corporate environment from a web
page and call
out to enterprise applications and "do bad stuff". They don't seem
to believe
in their own security implementation...
Gregg
The implementation of that interface uses JAAS to authenticate (I
have a
LoginModule that uses JNI interfaces to PAM for *NIX auth that I
"plugin" to
the server). If auth succeeds, execution continues to create an
instance of
the service object (if needed it might be a singleton depending on
the
application) and that is then wrapped by the authorization proxy
object which
is exported and wrapped into a Leased smart proxy which thus has
the remote
reference to the authorization proxy object on the server. That
smart proxy is
then what the client uses.
Gregg Wonderly
Thank you,
Peter.
On 8/9/2011 9:40 PM, Peter Firmstone wrote:
Gregg Wonderly wrote:
On 8/9/2011 7:57 PM, Peter Firmstone wrote:
I'm interested, I've been thinking about this too, what's your
current
service
interface?
The service interface is "the service interface". The mechanism
just uses a
proxy, delegating object. Thus, if you currently have a service
object, you
just create an instance of your security object, passing in the
service
object, and then export the security object for remote use.
That keeps you from having to support a "single" role model by
having that
codified into your application. Instead, the service can be
deployed with an
arbitrarily complex authorization implementation making it quite
flexible.
You
can even use Configuration to specify the security
implementation class.
Gregg Wonderly
So it implements the same interface as your service, but
encapsulates it.
So how do you log in, how does it track users? I'm guessing it's
got something
to do with associating threads.
Regards,
Peter.