Return-Path: Delivered-To: apmail-geronimo-dev-archive@www.apache.org Received: (qmail 36255 invoked from network); 25 Nov 2008 19:02:43 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 25 Nov 2008 19:02:43 -0000 Received: (qmail 41808 invoked by uid 500); 25 Nov 2008 19:02:51 -0000 Delivered-To: apmail-geronimo-dev-archive@geronimo.apache.org Received: (qmail 41767 invoked by uid 500); 25 Nov 2008 19:02:51 -0000 Mailing-List: contact dev-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list dev@geronimo.apache.org Received: (qmail 41756 invoked by uid 99); 25 Nov 2008 19:02:51 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 Nov 2008 11:02:50 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [98.136.44.59] (HELO smtp104.prem.mail.sp1.yahoo.com) (98.136.44.59) by apache.org (qpsmtpd/0.29) with SMTP; Tue, 25 Nov 2008 19:01:22 +0000 Received: (qmail 8822 invoked from network); 25 Nov 2008 19:01:07 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=Received:X-YMail-OSG:X-Yahoo-Newman-Property:Cc:Message-Id:From:To:In-Reply-To:Content-Type:Content-Transfer-Encoding:Mime-Version:Subject:Date:References:X-Mailer; b=yOWTL3eg7lUCKHC7iSU3ZJZmOW2d4Rl026f6Nate5rwv5hAgISLatEU4vdICRPvdzcl8hpda43iEJAjp2cLAaCZA2VeWZTKm0sqgjuO2uGUumXWyaa/w4b+5ikBhBK+k+Q2i89zgzeGUk4FAh1HMLe1GMPQr5fbJA5tz/UxIlBI= ; Received: from unknown (HELO ?10.11.55.45?) (david_jencks@63.105.20.225 with plain) by smtp104.prem.mail.sp1.yahoo.com with SMTP; 25 Nov 2008 19:01:06 -0000 X-YMail-OSG: cBmjGZMVM1nQXuu5J9OsJIoQNwSAYVkj.pj5PdRYvuslBlY4srVyAEpLtdqRhkJeOcRxIjoMBkAHkswv54iE98aKxpiGdUCJZSahqFE.2t2IHyYYzk.CBuloqx4MDYz.uISU0g6eqHz9lcvFCV3548nQifYi85hb20u9QtN8mJQqbiK4E5g4LqukPjo- X-Yahoo-Newman-Property: ymail-3 Cc: dev@jetty.codehaus.org Message-Id: From: David Jencks To: Jan Bartel , "Geronimo Dev List (JIRA)" In-Reply-To: <492C2D7B.4070001@webtide.com> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v929.2) Subject: Re: [jetty-dev] Jetty Security refactoring for JASPI Date: Tue, 25 Nov 2008 11:01:04 -0800 References: <48F837C4.50400@webtide.com> <49091DF7.3060300@webtide.com> <11DB9A16-A66A-4660-B884-194583D8C51F@yahoo.com> <490A9D83.6090503@webtide.com> <490AB702.9060508@webtide.com> <6332A153-A0AD-4C36-B8F7-D122E21A5F5B__1889.56977003745$1225472142$gmane$org@yahoo.com> <490ECAE5.802@webtide.com> <6859887D-3E1A-44A9-8042-BE12D8888553@yahoo.com> <4926B09A.9010905@webtide.com> <8491E01A-AF4A-4E4A-BC0F-39EB9C8A371F@yahoo.com> <49299DE3.2050403@webtide.com> <2BC5726A-037C-4D28-8F2A-C635412F258C@yahoo.com> <492ACCF0.4060507@webtide.com> <492C2D7B.4070001@webtide.com> X-Mailer: Apple Mail (2.929.2) X-Virus-Checked: Checked by ClamAV on apache.org Hi Jan, I've taken a very quick look at the AuthenticationManager you've added. It looks to me (based on this very non-thorough glance) that the main effect is to move some of the auth setup code out of WebXmlConfiguration and make it more accessible to programatic setup. For instance instead of having to know to use a BasicServerAuthentication you just need to know the string "BASIC". Is this more or less correct? I like the idea of making it easier to configure authentication like this, but I think there might be a more flexible and less intrusive way. IIUC the runtime authentication behavior still works through the ServerAuthentication interface, and the added methods on AuthenticationManager are only used for setup. If someone wanted to implement their own ServerAuthentication these extra methods wouldn't really provide any extra value. What if we had something like a DefaultAuthenticationFactory that you set up with the security handler and called configure(String authMethod, String loginPage, String errorPage, String realm) on and it constructed the appropriate [Basic|Digest|Form| ClientCert]ServerAuthentication and set it in the security handler? We'd need something similar for the jaspi approach. To me this would seem to separate the configuration and runtime aspects nicely while still providing the advantages of simpler configuration of the default auth methods. I haven't looked at your jaspi code yet.... jaspi configuration is a bit convoluted IMNSHO and I actually suspect anyone using a jaspi module may want to set it up directly in code rather than dealing with a whole jaspi provider (which I wrote for geronimo but not jetty specifically) I'll look at this in a bit. Moving the login services seems like a very good idea :-) thanks david jencks On Nov 25, 2008, at 8:53 AM, Jan Bartel wrote: > Hi David, > > I've made some changes to attempt to make jaspi vs non-jaspi > authentication pluggable. I've checked the changes in, as I > thought it is easier to see the code than talk about it. > > In a nutshell, I've introduced an AuthenticationManager that > is used by a SecurityHandler to carry out all authentication, > and which delegates to either a non-jaspi or jaspi implementation. > > The ConstraintSecurityHandler uses a DefaultAuthenticationManager > (non-jaspi) by default, but one can plug in the > JaspiAuthenticationManager > as an alternative. > > The WebXmlConfiguration sets up information from the web.xml such > as the auth method and login/error pages on the AuthenticationManager, > but no longer sets up the various auth modules such as Basic, Form, > Cert > etc. That is now done by the AuthenticationManager instance instead > when > it is started, based on the auth information passed into it by the > WebXmlConfiguration > (or programmatically of course). > > I've allowed for the JaspiAuthenticationManager to plugin a jaspi > auth module, > so that potentially we can plug in 3rd party jaspi auth modules. The > question is, > is the pluggability at the right level? That is, I've allowed a > ServerAuth instance > to be set on the JaspiAuthenticationManager, but the > JaspiServerAuthentication > class expects a ServerAuthContext instead (which all of the > FormAuth, BasicAuth > etc classes implement) - would a 3rd party jaspi module be likely to > implement > that interface? Should we be allowing for plugging in some other > class entirely? > > BTW I changed around a couple of packages, most notably the > HashLoginService and > JDBCLoginService I moved out of > org.mortbay.jetty.security.jaspi.modules and into > org.mortbay.jetty.security, as AFAICT they are not jaspi specific. > > I noticed along the way that the SSO stuff isn't really hooked up. > Difficult to > see how to shoe-horn that into the new structure. Perhaps its time > to ditch it > and allow for integration with "real" SSO implementations instead? > > The jaspi branch builds and tests without error, but I'm just > chasing down an > error when running the test webapp: > > Failed startup of context > org.mortbay.jetty.webapp.WebAppContext@1e59128{/,/home/janb/src/ > jetty-jaspi/webapps/test} > java.lang.IllegalArgumentException: Attempt to use undeclared role: > content-administrator, known roles: [] > > And the same for the test-jaas webapp: > > Failed startup of context > org.mortbay.jetty.webapp.WebAppContext@10ffb38{/test-jaas,file:/home/ > janb/src/jetty-jaspi/webapps/test-jaas/} > java.lang.IllegalArgumentException: Attempt to use undeclared role: > roleA, known roles: [] > > Looks like something amiss with the role merging, perhaps. > > Have a look at what I've committed, and please let me know what you > think. I'm all ears if > you've got any suggestions or a better way. > > cheers > Jan > > > > Jan Bartel wrote: >> David, >> [snip] >>>>>> BTW, the code needs to be reformatted to jetty standard >>>>>> conventions >>>>>> (http://docs.codehaus.org/display/JETTY/Jetty+Coding+Standards) >>>>>> or >>>>>> gregw will have conniptions ;) >>>>> hmm.... I thought I'd done pretty well imitating the code style. >>>>> Do you >>>>> have some way to fix it automatically? >>>> Lemme see ... as far as the brackets go, I have an eclipse >>>> codestyle >>>> that I can apply to each file, but the rigorous naming of data >>>> members >>>> with leading _ >>>> or __ would have to be done manually. >>> aha.... I can fix that, probably tomorrow. The brackets might be >>> tougher for me. >> >> I've reformatted and checked in classes in jetty and jetty-security >> packages. >> >>>> Correct me if I'm wrong, but the constraint preprocessing >>>> behaviour is >>>> separable >>>> from the jaspi authentication, so we could make that common >>>> between a >>>> ConstraintSecurityHandler >>>> that invoked non-jaspi authentication and another >>>> ConstraintSecurityHandler that invoked >>>> jaspi authentication? >>> The authentication (jaspi or ServerAuthentication) and authorization >>> (constraints or jacc or....??) are completely separable, but I >>> would >>> not try to guarantee that the behavior of the legacy constraint >>> security >>> handler would be unchanged if we combined the constraints up >>> front. If >>> you guys are willing to risk that the legacy behavior will change or >>> analyze it carefully enough so you're sure it won't, combining the >>> constraints up front would really simplify the code. I don't >>> understand >>> how the legacy code works well enough to be comfortable claiming >>> anything about it. >> >> Well, I think the existing "legacy" code is a bit difficult to >> understand, >> which is why I think it is clearer to go with your new structure that >> does the preprocessing. >> >> >>>> In terms of pluggability, I think so far I'm still leaning >>>> towards a >>>> default of current >>>> jetty authentication impl, with pluggability of the jaspi impl >>>> (probably via plugging in a >>>> JaspiConstraintSecurityHandler). >>> not sure what you mean here.... if you don't want to use the >>> ServerAuthentication, RunAsToken, and UserIdentity abstractions it >>> may >>> be difficult to switch back and forth. If you mean you want to >>> use the >>> [Basic|Digest|Form|ClientCert]ServerAuthentication implementations >>> for >>> the known auth methods rather than the jaspi modules, I >>> wholeheartedly >>> agree. >> >> What gregw has been discussing with me is the possibility to retain >> the >> existing jetty-7 authorization code, making judicious changes as >> necessary >> in order to permit a jaspi-flavoured implementation to be plugged >> in by >> choice. The new jaspi stuff could be debugged, profiled and generally >> kicked around a bit more until we could be comfortable that its at >> least as correct and performant (in the sense of least object >> creation >> per request, lazy auth all in the right places etc) so that it could >> then move to being the default authorization impl. >> >> Hence, a couple of emails ago I was starting to sketch out some >> ideas of how we could achieve that, but the code base has moved on >> somewhat since then, so I'm not sure how applicable those nascent >> ideas >> still are until I get a better grip on the changes. >> >> cheers >> Jan >> >> >>>> BTW, thanks for putting so much work into the security refactoring! >>> np! >>> >>> david jencks >>> >>>> >>>> Jan >>>> >>>> >>>>> thanks! >>>>> david jencks >>>>> >>>>>> >>>>>> cheers >>>>>> Jan >>>>>> >>>>>> David Jencks wrote: >>>>>>> Hi Jan, >>>>>>> >>>>>>> I rewrote the standard auth methods as ServerAuthentication >>>>>>> classes on >>>>>>> the plane ride home. I implemented Lazy and Caching (in >>>>>>> session and >>>>>>> SSO) as wrappers. Seems to compile but I haven't tried the >>>>>>> tck yet. >>>>>>> >>>>>>> I'm not sure if I've put in all the necessary stuff e.g. >>>>>>> timeouts?? but >>>>>>> I think this is a lot more plausible than the pure jaspi >>>>>>> implementations. >>>>>>> >>>>>>> thanks >>>>>>> david jencks >>>>>>> >>>>>>> On Nov 3, 2008, at 9:13 AM, David Jencks wrote: >>>>>>> >>>>>>>> Hi Jan, >>>>>>>> >>>>>>>> I'm about to hop on a plane so will respond in more detail >>>>>>>> later. >>>>>>>> >>>>>>>> I share your concerns about efficiency of the jaspi model, >>>>>>>> which is >>>>>>>> why I tried to put another hopefully efficient layer of >>>>>>>> interfaces in >>>>>>>> between the AbstractSecurityHandler and the jaspi auth >>>>>>>> modules. I >>>>>>>> was >>>>>>>> hoping that we could simply implement the known auth methods >>>>>>>> (FORM, >>>>>>>> BASIC,...) in terms of the ServerAuthentication interface >>>>>>>> directly >>>>>>>> and retain all possible efficiencies. Not having done it yet >>>>>>>> I might >>>>>>>> have missed some important points :-) >>>>>>>> >>>>>>>> I'll think some more about your comments and get back to you. >>>>>>>> >>>>>>>> thanks >>>>>>>> david jencks >>>>>>>> >>>>>>>> On Nov 3, 2008, at 1:56 AM, Jan Bartel wrote: >>>>>>>> >>>>>>>>> Hi David, >>>>>>>>> >>>>>>>>> Having pored over the jaspi spec a few more times, and then >>>>>>>>> having looked more closely at the code, I'm in a position to >>>>>>>>> give some more detailed comments. >>>>>>>>> >>>>>>>>> Firstly, I like the cleaner distinction in functionality >>>>>>>>> made with the UserIdentity and LoginService as compared >>>>>>>>> with the previous UserPrincipal and UserRealm. I also >>>>>>>>> like very much the refactoring of Abstract/ >>>>>>>>> ConstraintSecurityHandler >>>>>>>>> methods. >>>>>>>>> >>>>>>>>> Here's the place where your antennae should sense a "but" >>>>>>>>> coming :) >>>>>>>>> >>>>>>>>> But ... I have some reservations about the efficiency of >>>>>>>>> the Jaspi Way. In particular, every request for which there >>>>>>>>> is a role restriction will result in the user being fully >>>>>>>>> reauthenticated. I understand that even this is an >>>>>>>>> optimization and departure from the jaspi spec, which >>>>>>>>> requires validateRequest to be called on each and every >>>>>>>>> request, unless you know apriori that there is an exclusion >>>>>>>>> constraint for the resource of the request. BTW the lazy >>>>>>>>> authentication when there are no role constraints is another >>>>>>>>> good optimization. >>>>>>>>> >>>>>>>>> As there is going to be more authenticating going on as >>>>>>>>> compared with the previous situation, my next reservation >>>>>>>>> takes on more significance, and that is the amount of >>>>>>>>> object creation required to satisfy the convoluted jaspi >>>>>>>>> callback design. >>>>>>>>> >>>>>>>>> Finally, IIUC the FormAuthenticator will call >>>>>>>>> session.setAttribute(__J_AUTHENTICATED, form_cred) every time >>>>>>>>> authentication is done (see line 365 of FormAuthenticator). >>>>>>>>> In a clustered environment that would be undesirable. >>>>>>>>> >>>>>>>>> It seems to me that although we could tweak things a bit, >>>>>>>>> to make them more efficient, we'd be getting ever farther away >>>>>>>>> from the spec which does not seem to have efficiency as a >>>>>>>>> design goal. Do you agree, or do you have some optimizations >>>>>>>>> in mind? >>>>>>>>> >>>>>>>>> I'm wondering whether we could give the user the choice >>>>>>>>> of security implmentation, but making both jetty "default" >>>>>>>>> security AND jaspi security pluggable alternatives? I've >>>>>>>>> had a brief poke around and I don't think it would take that >>>>>>>>> much to achieve, but at this stage its a thought experiment >>>>>>>>> without code to show. >>>>>>>>> >>>>>>>>> The ideas I've been tossing around to make it pluggable are >>>>>>>>> to modify some of the interfaces of UserIdentity and >>>>>>>>> LoginService >>>>>>>>> and introduce a SecurityManager class to orchestrate >>>>>>>>> things a little: >>>>>>>>> >>>>>>>>> UserIdentity >>>>>>>>> ------------ >>>>>>>>> Principal getUserPrincipal() >>>>>>>>> String getAuthMethod() >>>>>>>>> boolean isUserInRole(String role) >>>>>>>>> setRunAsRole(RunAsToken) >>>>>>>>> setServletHandler(ServletHandler) >>>>>>>>> >>>>>>>>> >>>>>>>>> UserRealm (was LoginService) >>>>>>>>> --------- >>>>>>>>> UserIdentity authenticate (String user, Object credential) >>>>>>>>> boolean reauthenticate (UserIdentity) >>>>>>>>> >>>>>>>>> >>>>>>>>> SecurityManager >>>>>>>>> -------------- >>>>>>>>> UserIdentity authenticate (Request, Response) >>>>>>>>> >>>>>>>>> >>>>>>>>> DefaultSecurityManager //implements SecurityManager >>>>>>>>> ---------------------- >>>>>>>>> >>>>>>>>> >>>>>>>>> JaspiSecurityManager //implements SecurityManager >>>>>>>>> -------------------- >>>>>>>>> >>>>>>>>> >>>>>>>>> AbstractSecurityHandler >>>>>>>>> ---------------------- >>>>>>>>> + setSecurityManager (SecurityManager) >>>>>>>>> >>>>>>>>> The AbstractSecurityHandler would be pretty much unchanged >>>>>>>>> as it >>>>>>>>> is now, except for the addition of a setter and getter for a >>>>>>>>> SecurityManager instance, and the invocation of that manager >>>>>>>>> where it currently invokes >>>>>>>>> JaspiServerAuthentication.validateRequest(...) >>>>>>>>> (around line 169). >>>>>>>>> >>>>>>>>> The DefaultSecurityManager implementation would call the >>>>>>>>> authenticator >>>>>>>>> (Basic, Form, Credential etc) directly, much as the >>>>>>>>> ConstraintSecurityHandler >>>>>>>>> did in the pre-jaspi version. >>>>>>>>> >>>>>>>>> The JaspiSecurityManager implementation would be equivalent >>>>>>>>> to the >>>>>>>>> JaspiServerAuthentication class functionality. >>>>>>>>> >>>>>>>>> Perhaps the biggest change would be to the LoginService, >>>>>>>>> which I've >>>>>>>>> named back to UserRealm, simply because its behaviour is more >>>>>>>>> authentication related, rather than strictly login related. No >>>>>>>>> problem though >>>>>>>>> to keep the name LoginService if preferred. The authenticate() >>>>>>>>> method >>>>>>>>> returns a UserIdentity object, instead of ultimately setting a >>>>>>>>> LoginCallback >>>>>>>>> instance on the Subject (via the ServletCallbackHandler). I >>>>>>>>> don't >>>>>>>>> see that as a major problem - the ServletCallbackHandler >>>>>>>>> could set >>>>>>>>> the UserIdentity object on the Subject instead. Note that in >>>>>>>>> a jaspi >>>>>>>>> implementation, I expect that reauthenticate would never be >>>>>>>>> called, or >>>>>>>>> if it was, it would call authenticate() instead. >>>>>>>>> >>>>>>>>> The other issue is the Form, Basic, Digest etc AuthModules. >>>>>>>>> I think we'd need another set for the default jetty >>>>>>>>> implementation >>>>>>>>> that had no jaspi-style interfaces in it. I think though that >>>>>>>>> they should be able to share a majority of code - avoiding >>>>>>>>> duplication >>>>>>>>> would be highly desirable. >>>>>>>>> >>>>>>>>> From the user's perspective, it would be simple to configure >>>>>>>>> jaspi: >>>>>>>>> >>>>>>>>> WebAppContext webApp = ...; >>>>>>>>> webApp.getSecurityHandler().setSecurityManager(new >>>>>>>>> JaspiSecurityManager()); >>>>>>>>> >>>>>>>>> I'm sure I haven't considered all aspects of pluggability. >>>>>>>>> I'll try >>>>>>>>> and get some time to turn the thoughts into code, which are >>>>>>>>> a) more >>>>>>>>> easily >>>>>>>>> comprehended and b) will show up any areas I've neglected. >>>>>>>>> >>>>>>>>> cheers >>>>>>>>> Jan >>>>>>>>> >>>>>>>>> >>>>>>>>> David Jencks wrote: >>>>>>>>>> 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 @#*($)#@&^) >>>>>>>>>>>>>>>>> $@#&*$@ >>>>>>>>>>>>>>>> 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 | janb@webtide.com | >>>>>>>>>>>>>>>>> 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 | janb@webtide.com | >>>>>>>>>>>>>>> http://www.webtide.com >>>>>>>>>>>>>> >>>>>>>>>>>>>> --------------------------------------------------------------------- >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> To unsubscribe from this list, please visit: >>>>>>>>>>>>>> >>>>>>>>>>>>>> http://xircles.codehaus.org/manage_email >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> Jan Bartel, Webtide LLC | janb@webtide.com | >>>>>>>>>>>>> http://www.webtide.com >>>>>>>>>>>> >>>>>>>>>>>> --------------------------------------------------------------------- >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> To unsubscribe from this list, please visit: >>>>>>>>>>>> >>>>>>>>>>>> http://xircles.codehaus.org/manage_email >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Jan Bartel, Webtide LLC | janb@webtide.com | >>>>>>>>>>> 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 | janb@webtide.com | 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 >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> --------------------------------------------------------------------- >>>>>>> To unsubscribe from this list, please visit: >>>>>>> >>>>>>> http://xircles.codehaus.org/manage_email >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> Jan Bartel, Webtide LLC | janb@webtide.com | 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 | janb@webtide.com | http://www.webtide.com >>> >>> --------------------------------------------------------------------- >>> To unsubscribe from this list, please visit: >>> >>> http://xircles.codehaus.org/manage_email >>> >>> >>> >> >> > > > -- > Jan Bartel, Webtide LLC | janb@webtide.com | http://www.webtide.com