Yup, that's wrong.... should be fixed now

hoping to read your messages carefully before replying in the future,
thanks
david jencks

On Oct 31, 2008, at 12:42 AM, Jan Bartel wrote:

Hi David,

No, I'm referring to this code:

ConstraintSecurityHandler.checkUserDataPermissions line 235 and 259.

It is doing a redirect there to get the request to come in again on
the right connector (either the confidential or integral port as appropriate).

cheers
Jan

David Jencks wrote:

On Oct 30, 2008, at 10:54 PM, Jan Bartel wrote:

Hi David,

I'll reply to your reply in a later posting. For now, I just noticed
something odd in the ConstraintSecurityHandler. If
checkUserDataPermissions()
notices the request was received on the wrong connector (ie on http
instead of
https) and does a redirect, the AbstractSecurityHandler.handle()
method goes
ahead and subjects the request to JASPI authentication. It seems to me
that
at that point we want to stop processing the request altogether. It will be the redirected request that we're interested in processing further
(either doing the auth or doing a redirect to a login form).

I think you are referring to this code?

               if (!checkUserDataPermissions(pathInContext,
base_request, base_response, constraintInfo))
               {
                   if (!base_request.isHandled())
                   {
                       response.sendError(Response.SC_FORBIDDEN);
                       base_request.setHandled(true);
                   }
                   return;
               }

I think there's something odd here, but IIUC something other than what
you see.
This is not proposing a redirect, it is plainly denying the request.
I've been worrying about this because it prevents redirecting http
requests to the equivalent https requests.  Until recently I didn't
think it was possible to do this redirect using jacc permissions but I
think there is a solution....

If the actual request is denied and is http we could create a new
request with the url converted to https and checkUserDataPermissions on
it.... if that check succeeds we can redirect to the more secure url.
This is somewhat analogous to the way we determine if authentication is
mandatory, namely by doing a web resource permission check with the
unauthenticated user.

I might also have missed what you are looking at...

thanks
david jencks


cheers
Jan

David Jencks wrote:
Hi Jan,

On Oct 29, 2008, at 7:37 PM, Jan Bartel wrote:

Hi David,

I'm still snatching time to tiptoe further around the jaspi branch.

A couple of thoughts to run by you:

1. UserIdentity and LoginService classnames. These are quasi analogous
to UserPrincipal and UserRealm (although the behaviour has been
refactored).
I'm wondering whether it might not be a good idea to retain the old
classnames, just so it might be easier for jetty users/developers
to ease into understanding the new security structures?


I'm not sure that keeping the old names would help anyone understand the new code, I rather think it would be confusing. I'd really rather not call UserIdentity a Principal since it isn't a Principal and depending
on the security handler implementation can contain rather different
things. The main point of introducing it was that in jetty integrations
(Geronimo and from distant memory JBoss) the UserPrincipal was
ridiculously overloaded to contain incredible amounts of non- principal information associated with the user's identity. I think that instead it makes sense to have an object that supplies the UserPrincipal, plus whatever else the security system needs. I don't have strong objection
to calling the LoginService UserRealm but I think its going to be
confusing and less informative since it doesn't have the
non-login-service methods any more.

1a. Actually thinking about this, it will probably be quite
important for
Jetty users to be able to make a smooth transition over to a
jaspi-based
implementation. Do you think we can retain a UserRealm and a
UserPrincipal
with all their methods intact, but just "blend in" the jaspi- ness with some extra methods and some changed implementations of the existing
apis?


Maybe.  I think the new interfaces are a lot clearer and more
descriptive for embedding jetty that the old ones. I could look into writing adapters from UserIdentity to UserPrincipal and LoginService to UserRealm but I'm not entirely sure it will work. In particular I'm not at all sure the non login-service methods on UserRealm could plausibly
be called.

2. We allow a UserRealm to be explicitly set on a WebAppContext (well,
strictly speaking its
WebAppContext.getSecurityHandler().setUserRealm(UserRealm)).
I couldn't see specific support for that, only getting a list of
LoginServices from the Server instance. Should be easy enough to
put in though?

I'm not sure how my code is different, except the LoginService is final and set in the constructor of ServletCallbackHandler, around line 1042
of WebXmlConfiguration.  I don't recall changing this code much...



3. With the JAAS stuff, which has its own set of callbacks it
uses to obtain info, we used a DefaultCallbackHandler to plug in
the right info, such as credentials, passwords, usernames and
also extra request parameters from the login. I notice you're using
an anonymous CallbackHandler instead to pass into the JAAS
LoginContext.
Is it possible to use the DefaultCallbackHandler instead? It supports a couple more callback types that some LoginModule implementations may
depend on.

I could misunderstand the DefaultCallbackHandler but I think that the extensions to a user-password callback handler all involve extracting credentials from the request. In the jaspi architecture this is the function of the auth module, not the password validation service. A login module that fishes directly in the request ought to be refactored into a plain login module that just validates the credentials and an auth module that extracts the credentials from the message. Despite all the weirdness in jaspi I think this is a good idea and worth enforcing.

I guess someone who really really wanted to preserve their login module
could write a subclass of LoginCallback that dealt with request
parameters, and a JAASLoginService subclass. This would be made easier by factoring out the CallbackHandler creation in JAASLoginService into a protected method. Looks like I left out some exception handling there
too :-(  I'd rather not encourage this however.



4. Minor thing - is there a lot of value in the RunAsToken marker
interface
as opposed to just having a String? The roles and role mappings are
themselves just Strings, so I was wondering what the utility is?

This is an embedding thing also. It's pretty unclear what run-as is actually supposed to mean and how things like supplying the identity for a web service client or other remote call is supposed to work. (If the
web service is supposed to be called as the user, rather than the
server's identity, and you are in a run-as role, what credentials does
this run-as-role identity supply????)  In Geronimo we represent the
run-as role by a Subject obtained by logging into a security realm. So,
the geronimo run-as token has this Subject in it.  We might want to
store a UserIdentity there instead..... anyway I don't think
constraining the representation of the run-as identity is wise.

BTW remember that the current auth modules implementing
BASIC/DIGEST/FORM auth are more or less temporary until we more or less agree on the main interfaces, at which time I plan to rewrite them in
more jetty-friendly form (also after apachecon :-)

Many thanks!
david jencks



best regards
Jan

David Jencks wrote:

On Oct 16, 2008, at 11:59 PM, Jan Bartel wrote:

Hi David,

Firstly, let me genuflect in recognition of your extraordinary
efforts
for a) reading the spec b) being able to make heads or tails of it c)
coming up with an implementation based on it!

:-D


I'm surpressing the urge to have a bit of rant at yet another jcp
spec
that is at the same time heavy on the verbiage and light on
comprehensibility. Your email was way more informative
than what 29 people managed to produce in the spec.

Anyway, looking at the code in the jetty-7-jaspi branch, and I admit that so far I've only just had a cursory nosey around, where would we integrate the JAAS side of things? Implement a JAASLoginService?

see org.mortbay.jetty.plus.jaas in modules/plus/jetty-plus
Not sure if it is ideal, it's pretty much a simple modification of
the
former JAASUserRealm



I'll have a deeper look at the code and get back to you with more
informed comments. This mail is to re-assure you that your post
hasn't fallen into the void and that we are looking forward to
integrating this into jetty-7 trunk!

The main thing to remember might be that the current
implementations of
built-in security (FORM, BASIC, DIGEST etc) are in jaspi "modules"
only
until we agree on the jetty api at which point I was thinking to
convert
them back into more jetty specific code. Of course if you decide you
really like jaspi.... :-)


Jan
PS I love this code-comment in ServletCallbackHandler:

* Idiot class required by jaspi stupidity @#*($)#@&^)[EMAIL PROTECTED]&*$@

Several parts of the jaspi spec look to me as if they are sort of
stuck
on at the end when someone realized it was incomplete, and the
heavy use
of CallbackHandler for two way communication between the jaspi modules
and the container strikes me as one such point.

thanks
david jencks



:)

David Jencks wrote:
Greg and Jan were kind enough to create a branch for me to play
around
with a JASPI (Java Authentication Service Provider Interface)
integration with jetty and its getting to a point where I'm
willing to
talk about it.

Code is at
https://svn.codehaus.org/jetty/jetty/branches/jetty-7-jaspi

JASPI attempts to provide a uniform framework for messaging systems, both client and server side, to plug in message authentication. On
the
client you can add auth info to a request and validate auth info
on a
response. On the server you can validate auth info on a request
and add
auth info to a response.  The auth code can conduct arbitrary
message
exchanges to negotiate what info is needed and transmit the info.
I've
been working on the server side auth for jetty.

The actual spec jaspi interfaces are not 100% ideal for http and
don't
allow stuff like lazy authentication for unsecured resources so I've
come up with interfaces similar in spirit to the jaspi ones.

I've also tried to rework the implementation so it is more
friendly to
integration with other app servers with their own ideas about
security
frameworks such as geronimo and in particular make jacc
implementations
easier. I expect these changes will also simplify integration with
e.g.
jboss and glassfish but I haven't seriously tried to verify this.

Currently all the authentication code (replacing the *Authenticator classes) is implemented in terms of jaspi but I plan to change this
soon
to use the jetty specific interfaces directly.

So.... lets follow a HttpServletRequest/Response pair on its voyage
through the security system...


... it arrives at AbstractSecurityHandler.handle.  This is a
template
method that runs through the following structure calling out to
subclasses and the authentication system:
1. calls checkUserDataPermissions(pathInContext, base_request,
base_response, constraintInfo).  This checks the user data
constraints,
basically that the request arrived over the right kind of connection (http/https). Two obvious implementations of this are the existing
jetty constraint based implementation or one based on JACC.

2. calls isAuthMandatory(base_request, base_response,
constraintInfo) to
determine if the request actually needs authentication. If it does
not
we can often delay authentication until a method relying on auth
results
is called (such as getUserPrincipal or isUserInRole). Again this
can be
implemented using constraints or JACC.

3. packs the request, response, and authManditory into a
JettyMessageInfo holder object which can also pass various auth
info in
a map.

4. delegates the authentication to the jaspi-like ServerAuthResult
authResult = serverAuthentication.validateRequest(messageInfo);

assuming we are not doing lazy auth, this will extract the
credentials
from the request (possibly conducing a multi-message exchange
with the
client to request the credentials) and validate them.
Validation can use a LoginService possibly provided to the
ServerAuthentication which could be JAAS, Hash, JDBC, etc etc.
Lazy auth results in returning a lazy result that only attempts
authentication when info is actually needed.  In this case no
message
exchange with the client is possible.
<<<<<<<<<<<<<<<<<<<<
5. Assuming that authentication succeeded (this includes the lazy
case
where the request would be allowed even without authentication), we
wrap
up the result in an identity delegate:
     UserIdentity userIdentity = newUserIdentity(authResult);
     base_request.setUserIdentity(userIdentity);
The UserIdentity is the delegate for run-as role implementation and
actually answering auth questions from the application program.
This
allows app servers to handle run-as roles however they want.

6. Assuming authentication is mandatory, now that we know the
user, we
can find out if they are in the appropriate roles:
checkWebResourcePermissions(pathInContext, base_request,
base_response,
constraintInfo, userIdentity)

7. On success, we can actually handle the request:
getHandler().handle(pathInContext, messageInfo.getRequestMessage(),
messageInfo.getResponseMessage(), dispatch);

8. Assuming no exceptions were thrown, we can now secure the
response
(normally a no-op for http):
serverAuthentication.secureResponse(messageInfo, authResult);

-------------------------------------------

JASPI implementations

I wrote a fairly complete jaspi framework implementation for
geronimo
(rather than the bits actually needed for http which I wrote for
jetty)
and have a nearly-untested openid implementation.   This
(theoretically)
lets you openid-enable your app by supplying an appropriate login
page
and useing the openid auth module.

Theres also a glassfish implementation that I haven't looked at and
someone wrote a SPNEGO auth module that works with it.
http://spnego.ocean.net.au/

--------------------------------------------

How does this differ from what's there now?

SecurityHandler: AbstractSecurityHandler now just has the basic workflow described about and delegates all actual work to either subclasses (for authorization decisions and object creation) or the authentication delegate. This makes it easy to plug in alternate
implementations such as a JACC implementation for an EE server.

Authentication results and run-as roles: Formerly these were either directly set in the request (possibly using lazy evaluation, with
code
again in Request) or stuffed into a Principal implementation via the UserRealm. This really overloaded the idea of a Principal for no
apparent reason and made integration into app servers slightly
convoluted.  This is replaced with a UserIdentity interface
providing
separate access to the auth results (user principal) and role
handling
(isUserInRole, and run-as handling).  Subclasses of
AbstractSecurityHandler can provide their own implementations of
this
interface.  These typically delegate to implementations of
ServerAuthResult, which can handle lazy authentication if necessary.

UserRealm IMO glues together a lot of unrelated functions,
primarily the
role handling code now in UserIdentity and the credential
validation now
in LoginService. Credential validation may not even be needed by
the
server (e.g. openid). If needed it's called from something that extracts credentials from the request. Implementations are going
to do
something like look up the user in a file or table or delegate to
JAAS.
On the other hand the role handling is called by jetty or by the
application and the implementation is done by the app server
(jetty or
e.g. geronimo).  Aside from being related somehow to security,
these are
totally unrelated concerns.

--------------------------------------------------

How does ServerAuthentication and LoginService relate to JASPI?

The JASPI interface similar to ServerAuthentication is
ServerAuthContext:

void cleanSubject(MessageInfo messageInfo, Subject subject) throws
AuthException;

AuthStatus secureResponse(MessageInfo messageInfo, Subject
serviceSubject) throws AuthException;

AuthStatus validateRequest(MessageInfo messageInfo, Subject
clientSubject, Subject serviceSubject) throws AuthException;

The main difference is that ServerAuthentication packages all the results into a ServerAuthResult object rather than modifying the clientSubject directly and hiding user principal and group info in
some
callback handers. This lets ServerAuthentication support lazy auth.

As far as configuration goes. you get a ServerAuthContext by
calling a
whole lotta methods on some other stuff.  or.... you can just
create one
and stuff it into an adapter, JaspiServerAuthentication.
Probably we
want to implement the built in auth methods as direct
ServerAuthentication implementations rather than the current
ServerAuthModule implementations (a ServerAuthContext is supposed to
delegate to one or more ServerAuthModules, which have the same
interface).

LoginService is a pretty straightforward way of asking for password validation and getting some info back. JASPI has a peculiar IMO
system
based on Callbacks. The container (jetty) supplies the auth context with a CallbackHandler that enables bi-directional communication.
Callbacks providing services to the auth module:

PasswordValidationCallback: this lets the auth module ask for
password
validation: this is the closest to LoginService.
CertStoreCallback, PrivateKeyCallback, SecretKeyCallback, and
TrustStoreCallback all let the auth module ask for certificate
services. AFAICT these are mostly for securing response messages,
which
is typically not done for http.

Callbacks letting the auth module pass info to the server:
CallerPrincipalCallback: supplies the caller principal so
getCallerPrincipal can return something.
GroupPrincipalCallback supplies "groups" the user may be in. The meaning here is rather undefined but can be mapped to roles in some
way,
such as by assuming the groups and roles are the same.

The use of callbacks here still seems rather weird to me but may
make
more sense in the context of other messaging systems: jaspi is
supposed
to be applicable to all sorts of messaging, including ejb calls,
jms,
web services, etc etc.

I've put the caller principal and groups into the ServerAuthResult
object where they can be accessed directly (although possibly
determined
lazily).


--------------------------------------------------------------

Comments...

Right now it looks to me as if form auth needs to be non-lazy since
part
of the message exchange involves a request to j_security_check
which is
normally not a secured response. Trying to evaluate auth for this lazily doesn't work... you never get back to the original request.

I don't see how this implementation could be significantly
simplified or
sped up.... I'm certainly willing to look at problems.

I've been discussing JACC with Greg for a long time now. The only
thing
I can see that is possible with constraint implementations that
is not
possible with jacc is redirecting an http request to the
"equivalent"
https request if a user data constraint is violated. I'm curious
about
whether this is something people want to do or usually set up.

Many thanks,
david jencks







---------------------------------------------------------------------

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email





--
Jan Bartel, Webtide LLC | [EMAIL PROTECTED] | http://www.webtide.com

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email




---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email





--
Jan Bartel, Webtide LLC | [EMAIL PROTECTED] | http:// www.webtide.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

 http://xircles.codehaus.org/manage_email





--
Jan Bartel, Webtide LLC | [EMAIL PROTECTED] | http://www.webtide.com


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email





--
Jan Bartel, Webtide LLC | [EMAIL PROTECTED] | http://www.webtide.com

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply via email to