Refactoring Authenticated/Identified
|
View:
New views
9 Messages
—
Rating Filter:
Alert me
|
|
|
Refactoring Authenticated/IdentifiedContinuing this thread from the users list:
> Your suggestion of making authentication always 'fall through' might > be workable, but I'm not entirely sure that it's really what is needed. Now that we're on the same page about what I'm trying to achieve, I suspect you'll be able to come up with something cleaner than that. It still feels to me like I want to be somewhere between Identified and Authenticated, but given that the user data needs to be stored somewhere on the back end, you kind of need the hierarchy of backend storage types that the Authenticated subclasses give you (memory vs. db, purged vs. not, etc.) However, maybe that's a sign that the stuff in the Authenticated subclasses isn't actually in the right place to begin with. Consider it this way: Authenticated provides the logic to do different things depending on whether the user has a valid authenticated session, and the logic to manage that session (cookie management, etc.) That is its core purpose. The user and session data stores are really *inputs* to the authentication logic (or services it uses, if you prefer). Subclasses of Authenticated should be about changing the authentication logic, not changing which persistence service holds the user and session data. The persistence service is only loosely coupled to the authentication logic. The loose coupling I'm talking about is almost there already, in the form of the *Deployer classes, but the problem is that the selection of a Deployer is compiled into the Authentication class hierarchy rather than determined as an independent configuration setting. That means you can't subclass the authentication logic without making a parallel hierarchy of subclasses for the different combinations of storage types. So what I'm driving at is that the selection of the Deployer class should be purely a runtime configuration thing, and Authenticated should have none of its existing subclasses. I would add one aspect to the Deployer setup, though: the various stores should be configured separately rather than tied together. That is, there should be a SessionDeployer, CredentialsDeployer, and RememberDeployer interfaces, or whatever names make sense. The "mixed" case would no longer be its own concrete class, but just a configuration with a memory-based SessionDeployer and DB-based CredentialsDeployer and RememberDeployers. Then it'd be trivial for someone to substitute their own backend for one of those without touching the other one. For example, I will probably want a DB-based credentials store and my own session store that runs on a clustered memory cache. Vanilla RIFE sites won't know the difference: they will keep extending rife/authenticated/database.xml or whatever, and they never need to know that that file now has additional config parameters that cause stuff to be dynamically created on the backend. Once that refactoring is complete, it then becomes an almost trivial matter to do a subclass of Identified that knows how to pull the data for a user whose identity is known but who isn't currently authenticated. The subclass just uses the same Deployers as the authentication element and the rest happens for free. Before I said I might do it as a class in between Identified and Authenticated, but now I think I might do it as a superclass of Identified. I realize this is not your (Geert's) favorite way of thinking about the problem, but bear with me and maybe it'll make sense: RememberedSession (restores sessions from remember-me) Identified (looks up user ID from session ID) Authenticated (matches username/password) RoleUserAuthenticated (or should this logic be injected into Authenticated too?) The "remember me" logic (both creating and reading the cookie) moves into RememberedSession. If a session is restored from a cookie, the remember-me attribute is set just as today. The "prohibit remember" logic gets moved there too, so sites that want today's Identified semantics can still have them; if that flag is set, RememberedSession simply refrains from marking the request as part of a session. Identified and Authenticated will just see it as a request that doesn't have a valid session, no need for any special logic. That feels architecturally clean to me: it separates the three distinct questions that get asked on each page hit (is this a previously known user who wants to be remembered, is this a user we know about, is this user really who he claims to be) into separate classes. I think this will make the authentication system not only more flexible, but also easier to understand. YMMV on that though. -Steve _______________________________________________ Rife-devel mailing list Rife-devel@... http://lists.uwyn.com/mailman/listinfo/rife-devel |
|
|
Re: Refactoring Authenticated/IdentifiedAnyone have any comments on this idea? Is it a sensible approach or
crazy talk? If it's crazy, anyone have a better way to get the result I want? -Steve Steven Grimm wrote: > Continuing this thread from the users list: > >> Your suggestion of making authentication always 'fall through' might >> be workable, but I'm not entirely sure that it's really what is needed. > > Now that we're on the same page about what I'm trying to achieve, I > suspect you'll be able to come up with something cleaner than that. It > still feels to me like I want to be somewhere between Identified and > Authenticated, but given that the user data needs to be stored > somewhere on the back end, you kind of need the hierarchy of backend > storage types that the Authenticated subclasses give you (memory vs. > db, purged vs. not, etc.) > > However, maybe that's a sign that the stuff in the Authenticated > subclasses isn't actually in the right place to begin with. Consider > it this way: Authenticated provides the logic to do different things > depending on whether the user has a valid authenticated session, and > the logic to manage that session (cookie management, etc.) That is its > core purpose. The user and session data stores are really *inputs* to > the authentication logic (or services it uses, if you prefer). > Subclasses of Authenticated should be about changing the > authentication logic, not changing which persistence service holds the > user and session data. The persistence service is only loosely coupled > to the authentication logic. > > The loose coupling I'm talking about is almost there already, in the > form of the *Deployer classes, but the problem is that the selection > of a Deployer is compiled into the Authentication class hierarchy > rather than determined as an independent configuration setting. That > means you can't subclass the authentication logic without making a > parallel hierarchy of subclasses for the different combinations of > storage types. So what I'm driving at is that the selection of the > Deployer class should be purely a runtime configuration thing, and > Authenticated should have none of its existing subclasses. > > I would add one aspect to the Deployer setup, though: the various > stores should be configured separately rather than tied together. That > is, there should be a SessionDeployer, CredentialsDeployer, and > RememberDeployer interfaces, or whatever names make sense. The "mixed" > case would no longer be its own concrete class, but just a > configuration with a memory-based SessionDeployer and DB-based > CredentialsDeployer and RememberDeployers. Then it'd be trivial for > someone to substitute their own backend for one of those without > touching the other one. For example, I will probably want a DB-based > credentials store and my own session store that runs on a clustered > memory cache. > > Vanilla RIFE sites won't know the difference: they will keep extending > rife/authenticated/database.xml or whatever, and they never need to > know that that file now has additional config parameters that cause > stuff to be dynamically created on the backend. > > Once that refactoring is complete, it then becomes an almost trivial > matter to do a subclass of Identified that knows how to pull the data > for a user whose identity is known but who isn't currently > authenticated. The subclass just uses the same Deployers as the > authentication element and the rest happens for free. > > Before I said I might do it as a class in between Identified and > Authenticated, but now I think I might do it as a superclass of > Identified. I realize this is not your (Geert's) favorite way of > thinking about the problem, but bear with me and maybe it'll make sense: > > RememberedSession (restores sessions from remember-me) > Identified (looks up user ID from session ID) > Authenticated (matches username/password) > RoleUserAuthenticated (or should this logic be injected > into Authenticated too?) > > The "remember me" logic (both creating and reading the cookie) moves > into RememberedSession. If a session is restored from a cookie, the > remember-me attribute is set just as today. The "prohibit remember" > logic gets moved there too, so sites that want today's Identified > semantics can still have them; if that flag is set, RememberedSession > simply refrains from marking the request as part of a session. > Identified and Authenticated will just see it as a request that > doesn't have a valid session, no need for any special logic. > > That feels architecturally clean to me: it separates the three > distinct questions that get asked on each page hit (is this a > previously known user who wants to be remembered, is this a user we > know about, is this user really who he claims to be) into separate > classes. I think this will make the authentication system not only > more flexible, but also easier to understand. YMMV on that though. > > -Steve > _______________________________________________ > Rife-devel mailing list > Rife-devel@... > http://lists.uwyn.com/mailman/listinfo/rife-devel > _______________________________________________ Rife-devel mailing list Rife-devel@... http://lists.uwyn.com/mailman/listinfo/rife-devel |
|
|
Re: Refactoring Authenticated/Identified> Anyone have any comments on this idea? Is it a sensible approach or > crazy talk? If it's crazy, anyone have a better way to get the > result I want? Sorry Steve, haven't had the time yet to read it with the attention it deserves. I'll get to it this weekend. Take care, Geert -- Geert Bevin Uwyn "Use what you need" - http://uwyn.com RIFE Java application framework - http://rifers.org Music and words - http://gbevin.com _______________________________________________ Rife-devel mailing list Rife-devel@... http://lists.uwyn.com/mailman/listinfo/rife-devel |
|
|
Re: Refactoring Authenticated/IdentifiedHi Steven,
> The loose coupling I'm talking about is almost there already, in > the form of the *Deployer classes, but the problem is that the > selection of a Deployer is compiled into the Authentication class > hierarchy rather than determined as an independent configuration > setting. That means you can't subclass the authentication logic > without making a parallel hierarchy of subclasses for the different > combinations of storage types. So what I'm driving at is that the > selection of the Deployer class should be purely a runtime > configuration thing, and Authenticated should have none of its > existing subclasses. > > I would add one aspect to the Deployer setup, though: the various > stores should be configured separately rather than tied together. > That is, there should be a SessionDeployer, CredentialsDeployer, > and RememberDeployer interfaces, or whatever names make sense. The > "mixed" case would no longer be its own concrete class, but just a > configuration with a memory-based SessionDeployer and DB-based > CredentialsDeployer and RememberDeployers. Then it'd be trivial for > someone to substitute their own backend for one of those without > touching the other one. For example, I will probably want a DB- > based credentials store and my own session store that runs on a > clustered memory cache. > > Vanilla RIFE sites won't know the difference: they will keep > extending rife/authenticated/database.xml or whatever, and they > never need to know that that file now has additional config > parameters that cause stuff to be dynamically created on the backend. I think that this would be a very useful refactoring. Honestly, the tight bound between the deployer classes and the actual authentication elements has always somewhat bothered me. Actually, I can't believe that I never thought of doing this way. Then again, it has been awhile since I created custom authentication logic, so I can cut myself some slack. ;-) > Once that refactoring is complete, it then becomes an almost > trivial matter to do a subclass of Identified that knows how to > pull the data for a user whose identity is known but who isn't > currently authenticated. The subclass just uses the same Deployers > as the authentication element and the rest happens for free. > > Before I said I might do it as a class in between Identified and > Authenticated, but now I think I might do it as a superclass of > Identified. I realize this is not your (Geert's) favorite way of > thinking about the problem, but bear with me and maybe it'll make > sense: > > RememberedSession (restores sessions from remember-me) > Identified (looks up user ID from session ID) > Authenticated (matches username/password) > RoleUserAuthenticated (or should this logic be injected > into Authenticated too?) > > The "remember me" logic (both creating and reading the cookie) > moves into RememberedSession. If a session is restored from a > cookie, the remember-me attribute is set just as today. The > "prohibit remember" logic gets moved there too, so sites that want > today's Identified semantics can still have them; if that flag is > set, RememberedSession simply refrains from marking the request as > part of a session. Identified and Authenticated will just see it as > a request that doesn't have a valid session, no need for any > special logic. > > That feels architecturally clean to me: it separates the three > distinct questions that get asked on each page hit (is this a > previously known user who wants to be remembered, is this a user we > know about, is this user really who he claims to be) into separate > classes. I think this will make the authentication system not only > more flexible, but also easier to understand. YMMV on that though. Sorry, but I've still don't feel comfortable with this. As discussed before, you still seem to want to use the remember functionality for something that it hasn't been designed for. Its purpose really is to automate the provision of credentials to the authentication layer. It can't really be separated from it because the authentication checks still need to be performed every time credentials are retrieved and filled in automatically. Of all the previous suggestions that you've made, I think that the fall-through authentication solution seems the best to me (the one that doesn't require a form when no authentication session is present and no remember cookie can be found). It doesn't solve the theoretical use case of people that want to retrieve user credentials of accounts that haven't been registered as users to the authentication back-end yet, but it does solve your "eternal authentication session" problem without introducing an artificial embedded element. Take care, Geert -- Geert Bevin Uwyn "Use what you need" - http://uwyn.com RIFE Java application framework - http://rifers.org Music and words - http://gbevin.com _______________________________________________ Rife-devel mailing list Rife-devel@... http://lists.uwyn.com/mailman/listinfo/rife-devel |
|
|
Re: Refactoring Authenticated/IdentifiedGeert Bevin wrote:
> I think that this would be a very useful refactoring. Honestly, the > tight bound between the deployer classes and the actual authentication > elements has always somewhat bothered me. Actually, I can't believe > that I never thought of doing this way. Then again, it has been awhile > since I created custom authentication logic, so I can cut myself some > slack. ;-) Super, glad I'm not totally off the wall here. I have been doing some custom authentication code on both of my current RIFE projects (totally different on each, one is just the "remember me" stuff and the other is a custom Authenticated subclass that sends the user to a third-party authentication service to log in) so any movement in this direction will make my life much easier. What I'd love -- and I'm sure you would too -- would be to get to the point where a reasonably skilled developer could write their own, say, user database module without having to ever look at the RIFE source tree. Not that there's anything bad about having the sources to refer to, of course, but if my experience is typical, right now things are intertwined tightly enough that someone writing custom auth code has to be highly aware of the implementation details of the authentication system. This refactoring, assuming it turns out to be as feasible as it sounds, will definitely help in that area. I was not looking forward to figuring out how to explain the current Deployer system on the auth internals Wiki page. (Which, BTW, I am about to go work on a little more.) > Of all the previous suggestions that you've made, I think that the > fall-through authentication solution seems the best to me (the one > that doesn't require a form when no authentication session is present > and no remember cookie can be found). It doesn't solve the theoretical > use case of people that want to retrieve user credentials of accounts > that haven't been registered as users to the authentication back-end > yet, but it does solve your "eternal authentication session" problem > without introducing an artificial embedded element. I'm not sure I understand that use case. Can you give me an example? I've just filed RIFE-301 with an initial stab at an implementation of the fall-through mechanism. Seems to work just fine. -Steve _______________________________________________ Rife-devel mailing list Rife-devel@... http://lists.uwyn.com/mailman/listinfo/rife-devel |
|
|
Re: Refactoring Authenticated/IdentifiedHi Steven,
> What I'd love -- and I'm sure you would too -- would be to get to > the point where a reasonably skilled developer could write their > own, say, user database module without having to ever look at the > RIFE source tree. Not that there's anything bad about having the > sources to refer to, of course, but if my experience is typical, > right now things are intertwined tightly enough that someone > writing custom auth code has to be highly aware of the > implementation details of the authentication system. Indeed that would be awesome. I'm wondering, would you be up for making this refactoring happen? It will be quite a while before I can look at it. It's really time that I spend as much free time as possible on the book(s) and the advancement of continuations. > This refactoring, assuming it turns out to be as feasible as it > sounds, will definitely help in that area. I was not looking > forward to figuring out how to explain the current Deployer system > on the auth internals Wiki page. (Which, BTW, I am about to go work > on a little more.) > >> Of all the previous suggestions that you've made, I think that the >> fall-through authentication solution seems the best to me (the one >> that doesn't require a form when no authentication session is >> present and no remember cookie can be found). It doesn't solve the >> theoretical use case of people that want to retrieve user >> credentials of accounts that haven't been registered as users to >> the authentication back-end yet, but it does solve your "eternal >> authentication session" problem without introducing an artificial >> embedded element. > > I'm not sure I understand that use case. Can you give me an example? I was referring to the one I described in an earlier email: http://www.nabble.com/Re%3A-%22Remember-me%22-for-identified-%28not- authenticated%29-pages--p5592145.html > I've just filed RIFE-301 with an initial stab at an implementation > of the fall-through mechanism. Seems to work just fine. That looks like a good implementation of it. I would rename "allow_anonymous" to "enforce_authenticated", feels more logical and general-purpose to me. To implement the tests for this, I can point you to the related files. First, add the required elements to the authentication sites that are here: http://rifers.org:8088/browse/rifers/rife/trunk/ programs/unittests/config/site If you want, you can add the individual element XML files here, but I don't do that anymore: http://rifers.org:8088/browse/rifers/rife/ trunk/programs/unittests/config/element/authentication Then you add the actual tests to the JUnit suites that are here: http://rifers.org:8088/browse/rifers/rife/trunk/src/unittests/com/ uwyn/rife/authentication/elements To run only these, I simple comment out the non authentication test suites from: http://rifers.org:8088/browse/rifers/rife/trunk/src/unittests/com/ uwyn/rife/TestRifeTests.java?r=trunk and only leave the last bunch of server-side test suites in here: http://rifers.org:8088/browse/rifers/rife/trunk/src/unittests/com/ uwyn/rife/authentication/TestSuiteAuthentication.java?r=trunk To only use one database for testing, modify this file and prefix the "unittests*" names with another character (I use 'd' of disabled): http://rifers.org:8088/browse/rifers/rife/trunk/programs/unittests/ config/rep/unittests_datasources.xml?r=trunk Hope this is a bit clear, otherwise don't hesitate to ask. Take care, Geert PS.: I know that this would all be much easier if the tests were converted to TestNG ... but I'm not really up for that test ;-) -- Geert Bevin Uwyn "Use what you need" - http://uwyn.com RIFE Java application framework - http://rifers.org Music and words - http://gbevin.com _______________________________________________ Rife-devel mailing list Rife-devel@... http://lists.uwyn.com/mailman/listinfo/rife-devel |
|
|
Refactoring PurgingFirst a quick update for everyone reading this: I've done a first round
of the Authenticated refactoring, making the selection of the SessionManager and SessionValidator completely dynamic based on element configuration. There are no more Mixed element classes since they are just the database elements with the memory-based session classes configured in. Application code that uses rife/authenticated/mixed.xml won't notice the difference. But now for the real reason I'm writing this: While I was thinking about what I want to use this newfound configuration for, I had an idea about how to factor out the Purging stuff too. What I want to do is put a caching layer on top of the user and session data so I don't have to hit the database to fetch the data for a user who's currently logged in. But I *do* want a database sitting under the cache; whenever there's a cache miss the database should be consulted and the cache should be populated. So basically I want to wrap a caching facade object around the underlying database-capable objects. And it would be great to allow a stack of these facades, much in the same way we can stack child-trigger elements if we want to. Once that general mechanism is in place, purging is just another thing that can be layered on top of a SessionManager and/or RememberManager. In fact, the current implementations of PurgingSessionManager and PurgingRememberManager barely need to change at all; the only difference is how the system knows to instantiate them and what to wrap them around. And the purging behavior could be layered on top of, say, my caching wrapper. I think the general principle is probably not that controversial. The interesting question is, what does the configuration look like? And that's where I'm less certain. Spring actually has a reasonable syntax for configuring which beans are wrapped in which others -- you define the underlying bean, then define the wrapper bean and configure the underlying bean as a property of the wrapping bean. But since RIFE doesn't have an equivalent configuration mechanism for low-level objects, I think that might be a bit too heavyweight of a change to introduce. On the other hand, if we're willing to bite that bullet, it probably *is* the most flexible way to go about this. Instead, though, maybe something simpler is in order. Something like this (using some of the new properties I've introduced in my refactoring; hopefully it's easy enough to follow.) This is a definition for an element that uses a purging wrapper around a caching wrapper around a database session manager. First, database.xml (minus the stuff not related to session managers, for the sake of example): <element extends="rife/authenticated/authenticated.xml"> <property name="sessionmanagerfactory_class">DatabaseSessionsFactory</property> <property name="datasource"></property> <property name="sessionmanager_wrap_prefix">db_</property> </element> This is just like a normal (post-refactoring) session manager declaration: a factory class and the parameters it needs to instantiate its objects. The new thing is the last property; the easiest way to explain it is by proceeding to the next element, databasecaching.xml: <element extends="rife/authenticated/database.xml"> <property name="db_sessionmanagerfactory_class">SessionManagerWrapperFactory</property> <property name="db_sessionmanager_class">CachingSessionManagerWrapper</property> <property name="db_cache_size">1M</property> <property name="db_cache_expiration">LRU</property> <property name="db_sessionmanager_wrap_prefix">cached_</property> </element> Here all the properties are prefixed with the wrap prefix defined by the element we're wrapping. This prevents namespace collisions. All the classes involved will be able to take prefix arguments and will know to strip off their prefixes when looking up their properties. With that in mind, this looks similar to the initial element: we define a factory class (in this case, one that knows how to produce wrapper classes; it will pass the underlying database session manager to the wrapper's constructor) and tell the factory what underlying class to make. That underlying class has some properties. Then we define the next prefix in case there's another element in the chain, which in this case is in databasecachingpurging.xml: <element extends="rife/authenticated/databasecaching.xml"> <property name="cached_sessionmanagerfactory_class">SessionManagerWrapperFactory</property> <property name="cached_sessionmanager_class">PurgingSessionManagerWrapper</property> <property name="cached_purge_frequency">...</property> <property name="cached_sessionmanager_wrap_prefix">purged_</property> </element> Another wrapper as before, which also defines a prefix for the next link in the chain. But this time there isn't one. The session manager setup code will look for a "purged_sessionmanagerfactory_class" property on the current element, not see one, and will return the PurgingSessionManagerWrapper object to the caller. I admit the notion of using prefixes is a little wacky; you really *should* be able to use the same properties at each level so you don't have to change your element's properties just to wrap a different parent. But (as I just confirmed with Geert on IRC) the namespace of element properties is flat, so you pretty much have to do something like this to represent an arbitrary chain of parameterized objects. As with my current round of refactoring, this new flexibility is completely hidden from applications that just want to use the pre-canned "databaseunpurged.xml" or whatever. They continue to extend those XML files as before, blissfully unaware that stuff has gotten more dynamic under the covers. What do you guys think? -Steve _______________________________________________ Rife-devel mailing list Rife-devel@... http://lists.uwyn.com/mailman/listinfo/rife-devel |
|
|
Re: Refactoring PurgingHi Steven,
I think this should maybe better be solved by adding a single "sessionmanager_filter" property that can be injected through IoC. The objects should implement the SessionManagerFilter interface, which would then in turn extend the SessionManager interface. Instances of the filter classes are then simply setup for IoC in participants. One of the standard implementations can take a collection of filters that are processed sequentially. I'm thinking of maybe adding a setDelegate(SessionManager) method to SessionManagerFilter which will always be called to set the instance of the manager that is being wrapped. It would then be up to the filter to call the corresponding method on the wrapped manager if that's needed or to not do so if that's appropriate. I think that setting things up like this will be a lot easier that adding a whole bunch of properties with prefixes. What do you think? Geert On 07 Sep 2006, at 21:18, Steven Grimm wrote: > First a quick update for everyone reading this: I've done a first > round of the Authenticated refactoring, making the selection of the > SessionManager and SessionValidator completely dynamic based on > element configuration. There are no more Mixed element classes > since they are just the database elements with the memory-based > session classes configured in. Application code that uses rife/ > authenticated/mixed.xml won't notice the difference. > > But now for the real reason I'm writing this: While I was thinking > about what I want to use this newfound configuration for, I had an > idea about how to factor out the Purging stuff too. > > What I want to do is put a caching layer on top of the user and > session data so I don't have to hit the database to fetch the data > for a user who's currently logged in. But I *do* want a database > sitting under the cache; whenever there's a cache miss the database > should be consulted and the cache should be populated. > > So basically I want to wrap a caching facade object around the > underlying database-capable objects. And it would be great to allow > a stack of these facades, much in the same way we can stack child- > trigger elements if we want to. > > Once that general mechanism is in place, purging is just another > thing that can be layered on top of a SessionManager and/or > RememberManager. In fact, the current implementations of > PurgingSessionManager and PurgingRememberManager barely need to > change at all; the only difference is how the system knows to > instantiate them and what to wrap them around. And the purging > behavior could be layered on top of, say, my caching wrapper. > > I think the general principle is probably not that controversial. > The interesting question is, what does the configuration look like? > And that's where I'm less certain. > > Spring actually has a reasonable syntax for configuring which beans > are wrapped in which others -- you define the underlying bean, then > define the wrapper bean and configure the underlying bean as a > property of the wrapping bean. But since RIFE doesn't have an > equivalent configuration mechanism for low-level objects, I think > that might be a bit too heavyweight of a change to introduce. On > the other hand, if we're willing to bite that bullet, it probably > *is* the most flexible way to go about this. > > Instead, though, maybe something simpler is in order. Something > like this (using some of the new properties I've introduced in my > refactoring; hopefully it's easy enough to follow.) This is a > definition for an element that uses a purging wrapper around a > caching wrapper around a database session manager. > > First, database.xml (minus the stuff not related to session > managers, for the sake of example): > > <element extends="rife/authenticated/authenticated.xml"> > <property > name="sessionmanagerfactory_class">DatabaseSessionsFactory</property> > <property name="datasource"></property> > <property name="sessionmanager_wrap_prefix">db_</property> > </element> > > This is just like a normal (post-refactoring) session manager > declaration: a factory class and the parameters it needs to > instantiate its objects. The new thing is the last property; the > easiest way to explain it is by proceeding to the next element, > databasecaching.xml: > > <element extends="rife/authenticated/database.xml"> > <property > name="db_sessionmanagerfactory_class">SessionManagerWrapperFactory</ > property> > <property > name="db_sessionmanager_class">CachingSessionManagerWrapper</property> > <property name="db_cache_size">1M</property> > <property name="db_cache_expiration">LRU</property> > <property name="db_sessionmanager_wrap_prefix">cached_</property> > </element> > > Here all the properties are prefixed with the wrap prefix defined > by the element we're wrapping. This prevents namespace collisions. > All the classes involved will be able to take prefix arguments and > will know to strip off their prefixes when looking up their > properties. With that in mind, this looks similar to the initial > element: we define a factory class (in this case, one that knows > how to produce wrapper classes; it will pass the underlying > database session manager to the wrapper's constructor) and tell the > factory what underlying class to make. That underlying class has > some properties. Then we define the next prefix in case there's > another element in the chain, which in this case is in > databasecachingpurging.xml: > > <element extends="rife/authenticated/databasecaching.xml"> > <property > name="cached_sessionmanagerfactory_class">SessionManagerWrapperFactory > </property> > <property > name="cached_sessionmanager_class">PurgingSessionManagerWrapper</ > property> > <property name="cached_purge_frequency">...</property> > <property name="cached_sessionmanager_wrap_prefix">purged_</ > property> > </element> > > Another wrapper as before, which also defines a prefix for the next > link in the chain. But this time there isn't one. The session > manager setup code will look for a > "purged_sessionmanagerfactory_class" property on the current > element, not see one, and will return the > PurgingSessionManagerWrapper object to the caller. > > I admit the notion of using prefixes is a little wacky; you really > *should* be able to use the same properties at each level so you > don't have to change your element's properties just to wrap a > different parent. But (as I just confirmed with Geert on IRC) the > namespace of element properties is flat, so you pretty much have to > do something like this to represent an arbitrary chain of > parameterized objects. > > As with my current round of refactoring, this new flexibility is > completely hidden from applications that just want to use the pre- > canned "databaseunpurged.xml" or whatever. They continue to extend > those XML files as before, blissfully unaware that stuff has gotten > more dynamic under the covers. > > What do you guys think? > > -Steve > _______________________________________________ > Rife-devel mailing list > Rife-devel@... > http://lists.uwyn.com/mailman/listinfo/rife-devel > -- Geert Bevin Uwyn "Use what you need" - http://uwyn.com RIFE Java application framework - http://rifers.org Music and words - http://gbevin.com _______________________________________________ Rife-devel mailing list Rife-devel@... http://lists.uwyn.com/mailman/listinfo/rife-devel |
|
|
Re: Refactoring Authenticated/Identified
The refactoring I described in the original message of this thread is
now done and checked into the "authrefactor" branch in svn. Feel free
to check it out! Unless your application is directly messing with the
authentication elements (e.g. you have your own subclass of
DatabaseAuthenticated) this should be a completely invisible
refactoring.
You can now substitute your own classes for any of RIFE's authentication-related ones without having to write your own Authenticated element. If you crack open the element XML files such as authenticated/database.xml, you'll see a bunch of new config options that control which classes are used. Namely:
Comments and problem reports welcome. There will be one more round of refactoring before I consider this done: the purging vs. non-purging distinction is still hardwired into the class hierarchy. See the "Refactoring Purging" thread on this list for some idea of what I'd like to do with that. -Steve Steven Grimm wrote: Continuing this thread from the users list: _______________________________________________ Rife-devel mailing list Rife-devel@... http://lists.uwyn.com/mailman/listinfo/rife-devel |
| Free Forum Powered by Nabble | Forum Help |
