Tags:
create new tag
, view all tags

Archive for SmartSessionPluginDev

This archive was created on 04 Sep 2003 to clean up the clutter in SmartSessionPluginDev.

-- TedPavlic - 04 Sep 2003


SmartSessionPluginDevArchive Discussion: Page for developer collaboration, enhancement requests, patches and improved versions on SmartSessionPluginDevArchive contributed by the TWikiCommunity.
• Please let us know what you think of this extension.
• For support, check the existing questions, or ask a new support question in the Support web!
• Please report bugs below

Feedback on SmartSessionPlugin

Discussion here has much to do with SessionPlugin / SessionPluginDev as well.

Simple step-by-step instructions how to use this plugin are at SmartSessionCookbook


The rewrite is almost complete. All of the old features of SessionPlugin are completely incorporated along with some new configuration options.

Check out the new documentation and implementation at SmartSessionPlugin. Note that the plugin is still called SessionPlugin since that name is hard coded into Beijing TWiki.

Hopefully in the next couple of days I'll finish the transparent session ID feature which will relieve the plugin from even needing cookies to operate (think PHP sessions).

Remember that the main purpose of this rewrite was to provide a clean way a plugin could solve all of the TWiki:Codev/ImproveViewAuthentication and TWiki:Codev/BetterThandoRememberRemoteUser type problems. It does that in its current form.

I look forward to feedback.

-- TedPavlic - 17 Jul 2003

SessionPlugin was more of example code than anything (the variant used at work was more complicated and included talking to an LDAP server), so it's good to see more work in this area. Other than the URL rewrite work (not sure how close this is to completion and if it can work without core TWiki changes) and some configurable parameters, I'm not that clear what is different between SmartSessionPlugin and SessionPlugin. A couple of references are made to Codev topics above, but I'm unclear what SmartSessionPlugin does to help in these areas that SessionPlugin doesn't do.

-- JohnTalintyre - 19 Jul 2003

The use of CGI::Session allows for a number of improvements. For one, CGI::Session uses MD5 to generate the random session IDs, which is an improvement. On top of that, CGI::Session has configurable IP matching ability (this will be included shortly).

I have transparent session IDs working on www.osufirst.org. Nearly all of the use_only_once handlers had to be used in order to do this, but no patches needed to be done to TWiki to make this work. In fact, some of the regexps I've been using have made me submit some patches to the preview script so that it can catch (and not catch) as many hrefs as it does. I would have been happier using HTML::Parser (or a simpler parser) to catch those URLs inside forms, onclicks, and hrefs, but I didn't want to add another dependency on this plugin.

The MAJOR reason I ever went into creating SmartSessionPlugin was that I wanted a way to have persistent authentication, and SessionPlugin wasn't giving that to me. So a big part of SmartSessionPlugin is this code:

        $authUser = $query->remote_user() ||
                    $session->param( "AUTHUSER" ) ||
                    TWiki::Func::getDefaultUserName();

        # Save the user's information again if they do not appear to be a guest
        if( TWiki::Func::getDefaultUserName() ne $authUser )
        {
            $session->param( "AUTHUSER", $authUser );
        }

and then initializeUserhandler just returns $authUser. So how is this different from SessionPlugin? This way, once a user authenticates, that information is IMMEDIATELY stored into the session, thus making that information persistent. That was my main goal, and it works really well. Otherwise, I was using a patch I suggested in TWiki:Codev/BetterThandoRememberRemoteUser that seemed better to me than TWiki:Codev/ImproveViewAuthentication.

To me, what was already started in SessionPlugin with the idea of a logon script combined with what was added in SmartSessionPlugin almost solves the two bugs mentioned above. That is...

  • Modifying view to redirect to the logon script if TWikiGuest is logged on and otherwise go to the normal oops page
  • Keep logon information persistent so that it's never forgotten that someone has already logged on
  • Once someone logs on, immediately commit that information to memory (i.e., keep it persistent, but do this immediately at authentication rather than waiting for a session variable to be explicitly set somewhere)

Doing these three things together to me is pretty cool. (especially since you pointed out what logon's purpose was really for in a previous posting) That's a big part of why I'm so excited about SmartSessionPlugin.

-- TedPavlic - 21 Jul 2003

What do you mean by persistent? SessionPlugin deliberately only stored cookies in memory, as many users object to storage of cookies on disc (although this would be a useful option to offer to users).

-- JohnTalintyre - 22 Jul 2003

SessionPlugin stored cookies in data/.session as a number of files there. What do you mean about it storing cookies in memory? Storing cookies in memory would require an Apache module (one that may already exist) that would keep a large session database in memory persistently. Right now all the session solutions we've been talking about originate on disk.

SmartSessionPlugin and SessionPlugin both work the same way with regard to sessions. One happens to call CGI::Session to do a lot of the work for it, while the other one does it all manually, but they both store to disk. Am I misunderstanding you?

If you're referring to the USERS, SmartSessionPlugin and SessionPlugin BOTH use "per-session cookies" which immediately expire when the browser closes. When I said persistent, I didn't mean that the cookies stayed persistent on the client's machine. While it does seem like an interesting idea to have some sort of option to be able to use cookies that were not per-session, I think for now leaving that up to the authentication mechanism to "remember" logon information is probably best. Apache can remember usernames and passwords as an LDAP logon can remember as well.

I think I misunderstood some of the motivations behind SessionPlugin and you're misunderstanding some of my responses because of it. Until your recent post in SmartSessionPlugin, I didn't realize you were using third party LDAP authentication to securely authenticate and then pass session information (via session variable "user") to TWiki. Knowing that, then SessionPlugin is just as persistent as SmartSessionPlugin. By persistent, I was referring to view remembering that someone had already logged in. SmartSessionPlugin waits for Apache to setup the authenticated memory, whereas SessionPlugion waited for LDAP to do it. After that, they're equally as persistent in that authentication persists even on pages that do not require authentication by Apache (see discussions in AuthenticatedMode and NonAuthenticatedMode and such).

So that being said... Is there a way we can find a happy medium between using Apache for authentication and using that third party LDAP cookie source? I think a majority of TWiki users are using Apache's Basic authentication; it would be nice to make a session plugin which was sensitive to them and then figure out a way to fold in the other fringe users.

Any thoughts? (I guess we should probably concentrate discussion in one place rather than hopping back and forth... if it wasn't so late, I'd move the SmartSessionPlugin discussion here...)

-- TedPavlic 22 Jul 2003

I was referring to memory in the browser i.e. not storing cookies on the user's hard disc. SessionPlugin has always stored login information - it was an aside that at work we get this from LDAP. The mechanism is the same whereever the login is done.

-- JohnTalintyre - 23 Jul 2003

Looking at SessionPlugin, I see (in sub initializeUserHandler):


    if( ! $user || $user eq &TWiki::Func::getDefaultUserName() ) {
        if( $sessionInfo{"user"} ) {
            $user = $sessionInfo{"user"};
        }
    } else {
        setSessionValueHandler( "user", $user );
    }

    return $user;

This does not handle any authentication except for ones that manually set "user" in the session. This mechanism does not keep user information persistent unless other mechanism sets "user" in the session. There's nothing that links $query->remote_user() to "user".

I'm assuming that your LDAP server would authenticate and generate a cookie with a session ID, set "user" in that session, and then return to you. That cookie would then tell TWiki to call up that session. That session would then have "user" in it. Then initializeUserHandler would return that to TWiki as the authenticated username.

As mentioned above, SmartSessionPlugin looks for $query->remote_user() to set an "AUTHUSER" within it. To make it compatible with the mechanism that is installed in SessionPlugin, it would also need to store that same information in a "user" as well as look to "user" right after it looked to $query->remote_user().

I know that SessionPlugin simply was not authenticating, as my Apache Basic Authentication wasn't making a dent in it. However, SmartSessionPlugin responds to Apache's basic authentication easy by respnding to changes in $query->remote_user().

How are you proposing that SessionPlugin responded to any authentication but very proprietary ones?

-- TedPavlic 23 Jul 2003

The plugin seems to break bin/mailnotify (as that has no session). The following fixes that (though there might be a better way to do it).

--- lib/TWiki/Plugins/SessionPlugin.pm  2003-07-17 05:35:19.000000000 -0400
+++ lib/TWiki/Plugins/SessionPlugin.pm    2003-07-27 14:43:08.000000000 -0400
@@ -272,6 +272,7 @@
     # This handler is called by TWiki::getSessionValue. Return the value of a key.
     # Use only in one Plugin.
     # New hook in TWiki::Plugins $VERSION = '1.010'
+    return undef if (!$session);

     return $session->param( $_[0] );

@@ -353,9 +354,8 @@
 # which CGI variable to look at.
 sub _init_stickskin()
 {
-
     # See whether user has decided to set a stickskin
-    $stickskin = $query->param( "stickskin" || $stickSkinVar );
+    $stickskin = $query->param( "stickskin" || $stickSkinVar ) if ($query);

     # If a stickskin has been selected, save it in the session
     if( $stickskin ) {

-- MalcolmJHarwood - 27 Jul 2003

Eek. Wow. Really excellent point. On my development TWiki webs, I don't have notify turned on. I hate having to couple cron to web applications; it doesn't make as much sense to me.

I've made quite a few changes in SmartSessionPlugin to clean it up and add a bit of security to it. For example, it now can be configured (by default this is turned on) to make sure that a session's IP matches the IP from which it is currently being called. This hopefully prevents people from borrowing session IDs from other people to gain access to a TWiki web.

An increase in "real work" has prevented me from finishing off polishing up the regular expressions that make the transparent CGI session IDs work. I'm still flirting with the idea of using a simple HTML parser from CPAN, but I'd hate to make the module have yet another CPAN dependency, and already scripts like bin/preview using regexps instead of real parsing, so I figure I might as well follow suit.

I'm also flirting with the idea of making the session user ID variable configurable (rather than the hard-coded "AUTHUSER" it already is). I don't initially see any problems with this, and it would make the code backwards compatible with SessionPlugin that uses "user" and reminds me that people might use other authentication schemes that create the session for them.

I'd also like to think about making the session serializer more configurable. But I don't plan on doing anything with that any time soon.

The moral of the story is that the "release" version has a slightly different architecture. I'll incorporate these changes into it. Hopefully I'll be able to upload it very soon.

Thanks for the patch to the alpha.

-- TedPavlic - 28 Jul 2003

Hi,

I would be very interested in testing this and seeing if it could be made to work with mod_ntlm/sspi on windows. At the moment I am having problems with TWikiDraw breaking, I think because of not using the basic auth, and I hope the persistent auth stuff will fix this...?

-- EdWildgoose - 30 Jul 2003

Ed, I cannot comment on TWikiDraw breaking. Check in TWikiDraw and TWikiDrawDev for details.

However, regarding persistent authentication, as long as cookies are turned on the current version of SmartSessionPlugin available here will provide that for you.

For some alternatives, you should take a look at BetterThandoRememberUser and ImproveViewAuthentication. Various different ways of getting persistent authentication to work are discussed there.

As a quick test, you might try looking in your TWiki.cfg file and turning $doRememberRemoteUser on. This will remember the IP's of users as they visit. When a user returns with the same IP (within a certain time threshold?), TWiki will assume the user is still logged in.

Regarding mod_ntlm/sspi... As long as $ENV{REMOTE_USER} (i.e., $query->remote_user) is set in the environment after the user is authenticated, this plugin will work fine.

The "final" release of SmartSessionPlugin will be available soon. Major improvements over the current version include:

  • Not breaking mailnotify (see patch above)

  • Turning transparent CGI session IDs on

  • Turning IP match security on (i.e., making sure sessions always come from the same IP to be valid)

  • Turning user session match on (i.e., making sure that if a new user logs in, if an old session is attempted to be used, it will be deleted)

-- TedPavlic - 30 Jul 2003

Hi, thanks for that note. Well TwikiDraw breaking is entirely down to the fact that it starts a new connection to the server, but then of course it tries to auth but can't because only ntlm/sspi is enabled (and that only works IE).

I have worked around this by turning on the Basic Auth fallback, but it would be nice if you had a clever way to work around this? Bear in mind that the java applet is presumably starting a new connection and hence I guess a new session with the server (although I guess with modifications it could be persuaded to share?)

-- EdWildgoose - 31 Jul 2003

Does somebody solve problem with SmartSessionPlugin + SpeedyCGI (mod_perl) ?

-- IvanGrynov - 14 Aug 2003

Could you be more specific? What problem?

-- TedPavlic - 16 Aug 2003

I've just uploaded version 2.102 to SmartSessionPlugin. This version not only adds a number of useful features, but it seems to fix the mailnotify bug mentioned above. Because it fixes this bug, I ANTICIPATE that it will fix other bugs related to it.

Of the features it adds, many more items are now configurable, and it allows for the use of transparent CGI session IDs, which remove the need for cookies (though they clutter URLs making copying and pasting more difficult).

It also removes a number of warnings it was generating in error_log due to perl -w being anal.

Let me know

  1. Any feedback
  2. More details on this SpeedyCGI problem (are you saying that with mod_perl it never "forgets" the current user or something?)

-- TedPavlic - 17 Aug 2003

Ted, I'll like to use your plugin, but I am not sure how exactly. I managed to set up authorisation with "doRememberRemoteUsers" on. I might need detailed step-by-step guide focused on how to do stuff your way, not all 3 possibilities mixed. I am far from Linux guru, or security expert.

-- PeterMasiar - 19 Aug 2003

Quick Installation Instructions (also see Installation Instructions)

Peter, I'm guessing you're saying that my documentation says far too much? smile Maybe I need a "Quick start" or something like that?

The quick start is:

  • Install the plugin into twiki/lib/Plugins/SessionPlugin.pm

and that's it. As long as your web server has access to your /tmp directory to write its session files, you'll start using session information and will not need $doRememberRemoteUser anymore.

Now, there are various configuration options which may be useful to you, but the defaults are fine. Most of the "interaction" with sessions would only occur within other plugins. Sessions are meant to provide useful ways of storing information from page to page without having the user post it every time over their link. However, few plugins currently exist that need sessions.

So why use them? Well, built into SmartSessionPlugin is the ability to remember logon information and "sticky skin" information, so SmartSessionPlugin becomes a client of its own services.

These two features combined -- the ability to store session information and the ability to use sessions to maintain persistent logons over a session -- are enough to give SmartSessionPlugin a great deal of value, even though it's fairly transparent.

You're not supposed to ses SmartSessionPlugin working, and that's one of the reasons why it's so smart. By default, if the user does not have cookies installed, it even continues to work by adding its session identifiers to every URL on the fly without anyone but the keen observer even noticing.

So here's the quick few steps to get you up and running and test to see if SmartSessionPlugin is working:

  1. Untar the archive into your twiki distribution making sure that
    • SessionPlugin.pm is in your lib/TWiki/Plugins directory
    • SessionPlugin.txt is in your data directory
  2. View any page on your TWiki web. You should not notice any differences. There should be no errors or bells and whistles. If your web browser is configured to notify you that you are receiving a cookie, you MAY notice that notification pop up.
  3. Add to any URL the text &stickstin=plain. You should notice that from then on out your browsing experience should look very different. If you close your browser and come back, things will look normal again. If you add &stickskin=default to the end of the URL after you've "plain-ized" it, it will also convert back to normal.
  4. Go to any page that has the TWikiVariable %WIKINAME% on it. You may want to edit a page and put %WIKINAME% on a page. If SmartSessionPlugin is working, then a user who has not logged in yet will view that page and see TWikiGuest, but a user who has logged in will see his or her WikiName. If SmartSessionPlugin is not working, it will always say TWikiGuest unless you are previewing it.
    • You will need to turn OFF $doRememberRemoteUser to truly test this.
    • You should have NO NEED for $doRememberRemoteUser anymore PROVIDED THAT
      • You are willing to require your users to use cookies
      • OR you are willing to leave the default "use transparent CGI session ID" option ON which may make your URLs look funny if someone happens to notice

The only speed bumps you may have are if:

  • Your /tmp directory is not writable by the webserver
    • You will need to provide a directory writable and readable by the webserver for storing its session files. The location of this directory is hard-coded into SessionPlugin.pm, but it is easy to find.

  • You wish to change the IP_MATCH or AUTHUSER_SESSIONVAR variables, which are also hard-coded into SessionPlugin.pm

But otherwise, the default settings should work fine. The only thing you might consider doing is turning OFF transparent CGI session IDs if you don't like how it changes your URLs on the fly. Note that it AUTOMATICALLY TURNS OFF once it receives a COOKIE FOR THE FIRST TIME. Once it's convinced the user can use cookies, it stops playing with the URLs.

I hope that wasn't too much information to further confuse things. frown Hopefully you'll try downloading the distribution, installing it, and it'll just work. big grin

-- TedPavlic - 19 Aug 2003

The logon script (optional)

Also note that if you want to use TigerSkin or GnuSkin's "logon" features, you will need to follow the bin/logon instructions, which explain how to add the three lines to your bin/.htaccess file to make this work.

Further details are given at the end of SmartSessionPlugin under the Installation Instructions.

-- TedPavlic - 19 Aug 2003

CPAN Dependencies

Also note that this requires the installation of the CGI::Session perl module from CPAN. If you are running RedHat or Mandrake or a number of other Linux releases that have a package manager, there is most likely a package which will install this for you. If you have a web presence provider, they may already have this package installed or will very EASILY be able to install it for you (note that you can install it yourself in your twiki/lib directory if you're willing). If you install SmartSessionPlugin and pages fail to load (you'll notice immediately) because of a missing CGI::Session, remove SessionPlugin.pm until the CGI::Session gets installed.

Note that CGI::Session depends upon a few other commonly (in Perl 5.8.0, these come "standard") installed Perl modules. These two immediately come to mind:

If you have never installed a CPAN component, it usually consists of untarring the component's source, doing a:

  • perl Makefile.PL
  • make
  • make test
  • make install

Of course, if you are installing into your twiki/lib, there are some more manual steps after make test. Hopefully you won't have to go through much of that.

-- TedPavlic - 19 Aug 2003

Ted, you are my man. smile PluginsForDummies - as I like it. Thank you

-- PeterMasiar - 19 Aug 2003

Here is details about SpeedyCGI problem:

I tried to rewrite it and investigated some problems.

  1. _init_authuser has to be invoked every time from initPlugin. In current version it runs only once when script is loading to memory.
  2. $session should keep up to date file on the disk every time because of problem with two scripts in memory with the same session ID (they will have two or more different versions of session data).

-- IvanGrynov - 19 Aug 2003

The nearest machine I have access to to install SpeedyCGI on is 1200 miles away in a place I won't see for another month. smile So, I'm going to just have to speculate, give some hints and ideas, and see what other people think.

First, some explanation for what _init_authuser does:

  1. If already run, return true immediately.
    • Otherwise, remember that it is being run currently so that next time it is called within this instance, it will return immediately.
  2. Next, use CGI::Session . . .
    • to get a cookie or a CGI session variable from the user identifying their session
    • if the user has identified a session . . .
      • find that session on disk and load it into memory
      • if that session's stored username or IP address does not match current user, then clear the session and start a new one
      • if that session does not exist or does not have a stored username in it AND the user is currently authenticated, store the user's authenticated name into the session
      • if that session has a valid stored username in it, make that the user's authenticated name
        • this is where the magic occurs that makes for persistent authenticated logons
        • this is also the reason why init_authuser _must be run so early. This username stuff has already been settled for good by the time initPlugin is run
        • this also means that running it every time in initPlugin won't help anyone authenticate
        • _init_authuser simply MUST run before anything else runs in order to set the user's authenticated username trusted by the TWiki core; is it even POSSIBLE for this to happen without a rewrite of how some of the plugin code is written/loaded? Perhaps a new handler is needed?
    • if the user has NOT identified a session, create a blank one for them and, if possible, write the current authenticated user name to the session

And that's it. It's fairly simple. But CAN it be fixed within SmartSessionPlugin? I am not convinced it can.

-- TedPavlic - 20 Aug 2003

I have moved the thread started by DuncanInnes to the Support web as it appears to be a local problem. If there is a problem with the plugin, I will post details of the problem and its fix here.

The support thread in question is SmartSessionPluginNotLoading.

-- TedPavlic - 20 Aug 2003

How does one terminate the session?? For example in the TigerSkin & GnuSkin there is a logon script, Im looking for a way to "logoff". Any suggestions???

-- JohnCavanaugh - 20 Aug 2003

This is a tricky subject. The only real way to "logoff" is to close the browser and open it again.

I know that seems unreasonable, and I thought of making a "bin/logoff" that would clear a current session. However, the problem is that a great majority of TWiki webs use Apache's "basic authentication" to authenticate, and this is what sets the REMOTE_USER that works with SmartSessionPlugin. There is no way (that I know of?) to force a browser to stop sending the same authentication information over and over again without just closing the browser, I didn't figure it would be of much use to erase the session. That is, once a session is cleared, a new one will be created, and the first time the user hits a page that requires authentication, the session will suddenly inherit all the user's settings and he or she will be back where he or she started.

The ONLY advantage (in most situations) to having a bin/logoff is that it would allow a TWikiGuest who had setup session variables (to my knowledge, the only ones that are used involve the "sticky skin" features of SessionPlugin) to clear them.

So there is never any way to "log off" until someone comes up with a way to force a browser to stop authenticating with the last authenticated information it cached. Does that make sense? The first time someone goes to an authenticated page, the browser prompts for a username and password. After that, the browser sends to every other authenticated page that same information until the browser is closed and re-opened. SmartSessionPlugin has just inherited this limitation from the "basic authentication" used by most users of TWiki.

Now, I can imagine someone coming up with a logon scheme that does not use "basic authentication" but still gives SessionPlugin enough information to keep authentication persistent, but the cleverness of that logon scheme would also make IT able to clear the session... so the burden of logging out resides with that clever scheme. I repeat, the burden of logging out does not fall on SmartSessionPlugin (or SessionPlugin, that is).

So until someone comes up with a better way, you have to close your browser.

-- TedPavlic - 21 Aug 2003

I checked IE and Mozilla Firebird - multiple instances of the same browser somehow communicate and identity from one instance is used in other (but not between different browsers, ie not between IE and Mozilla). Does all browsers behave this way?

If I have doRememberRemoteUsers set to NO (off) and plugin is installed, and user edited some page (so identity is known): will be WIKIUSERNAME set to username also in view mode? I guess I need to try out. Oh well, where is my newbie Linux admin hat?

-- PeterMasiar - 21 Aug 2003

I thought I had responded earlier to this, but it appears like I must not have saved. Sorry about the delay.

I'll address both of your questions directly here. The short answer is that what you observe is what is expected, and you will not need $doRemememberRemoteUser ever again as long as you trust your user's use cookies and you leave "transparent CGI session IDs" turned on (as it is by default).

  • Multiple Instances of the Same Browser Type Share Cookie Information and Thus Share Login Information

What you have observed is what is expected. Currently you are using cookies to toss back a token which identifies you to the server. The cookies are stored within each browser and erased when the browser is closed. However, if you create a new instance of a certain browser, it will share its cookie information with its parent.

Now, if you open up a totally different browser, there is no way that other browser has access to the first browser's cookies, so it will start a session with a totally new cookie. Of course, every instance of this new browser will share local per-session cookies with other instances of itself, but it cannot somehow export these cookies.

To put things in more specific terms, every instance of MSIE has access to a shared store of per-session cookies on your machine. This store exists for MSIE and MSIE alone. Every instance of MSIE has access to these cookies and will be able to respond to SmartSessionPlugin with them. However, once every instance of MSIE is closed, that particular per-session cookie will be obliterated and forgotten.

This goes the same for Firebird. It can share its own cookies with other instances of itself, but MSIE has no idea these Firebird cookies exist. Once every instance of Firebird is closed, that cookie will be lost forever as well.

Now, if "transparent CGI session IDs" are used, this becomes a little different as those are not based on cookies as they are on URLs with special variables explicitly specified in them. I don't think it's necessary to get into the distinction between the two.

For more information, I recommend taking a look at the long-winded introduction in the SmartSessionPlugin page or look up details on how cookies work.

  • Turning $doRememberRemoteUser off when SmartSessionPlugin will still cause user identities to be remembered after an authentication even on public pages

One of the purposes of SmartSessionPlugin was to make it so that TWiki administrators do not need to use $doRememberRemoteUser for authentication information to be remembered after a logon. Once a user logs in, their username is stamped onto their session. As their session information is given to every page regardless of its "need authentication" state, this logon information follows them around the site. However, rather than being tied to their IP, as it is with $doRememberRemoteUser, it is tied to their session. The session, as explained above, is tied to their web browser and expires immediately when all instances of the web browser are closed.

-- TedPavlic - 22 Aug 2003

Version 2.111 was just uploaded. The major addition is that of the conditionals that allow a TWiki site to display different text to authenticated users than to non-authenticated users.

This suggestion was requested so that non-authenticated users would see a logon prompt while authenticated users would see a link to their TWiki user pages. This is now easily possible with the conditionals provided in version 2.111.

-- TedPavlic - 23 Aug 2003

I identified a bug in Prefs.pm that causes session variables to override FINALPREFERENCE variables. Details can be found at SessionVariablesOverrideFinalPreferences.

Now, currently this only appears to be a major problem with SKIN, as SmartSessionPlugin directly allows a user to play with the SKIN TWikiVariable via the "sticky skin" features.

I am considering adding (perhaps tonight) to SmartSessionPlugin the ability to get and set session variables via TWikiVariables directly on a page. For example:

<pre>
%<nop>SET_SESSION_VARIABLE{ 'SKIN' = 'plain' }%

%<nop>GET_SESSION_VARIABLE{ 'SKIN' }%
</pre>

or something along those lines. I'm not entirely sure how useful this would be, but right now session variables really can only be used by other plugins that depend upon SessionPlugin or SmartSessionPlugin. It only seems to make some sense that these variables be accessible in a more direct fashion... I still have to give it some thought, but this change would be a quick and easy one. Unfortunately, it would make it easy to exploit modifying FINALPREFERENCE variables (including %FINALPREFERENCES% itself) without the patch I give in the bug entry I mention above.

-- TedPavlic - 24 Aug 2003

The above changes have been made. The new SmartSessionPlugin that supports setting and clearing session variables from within a TWiki page as well as from CGI and supports viewing session variables within a TWiki page takes the form of version 2.121.

As I cannot anticipate any other session-related features to jam into this plugin, I should hope that (aside from perhaps bugfixes?) this plugin should settle down a bit.

A quick summary of recent additions to the plugin:

  • New %SESSION_IS_AUTHENTICATED% flag that changes from 0 to 1 after authentication occurs
  • New %SESSION_IF_AUTHENTICATED% type conditionals that allow a TWiki web page to look significantly different after authentication
  • New %GET_SESSION_VARIABLE% (and similar for SET and CLEAR) TWiki variables that allow session variables to be set right on TWiki page directly (see SessionVariablesOverrideFinalPreferences for security warning due to TWiki core bug; a fix is available there as well)
  • New sensitivity to CGI variables set_session_variable and clear_session_variable that can set and clear session variables before a TWiki page loads; these can actually be used to replace the sticky skin features and implement sticky everything features.

These additions were made partly because some were requested off-line and partly because they were the final puzzle pieces in my picture of a complete useful session plugin.

-- TedPavlic - 24 Aug 2003

Ted, you stated on another page (TigerSkinPluginDev) that the SESSION variables above would only be useful to skin designers if they knew which version of the session plugin was installed. Can you load SmartSessionPlugin in such a way that it makes the core think that both SessionPlugin and SmartSessionPlugin are loaded?

Then if the skin (or its supporting package) detected that SmartSessionPlugin was defined, it would use the enhancements in your plugin. Otherwise it would behave as it would for the original SessionPlugin.

-- JohnRouillard - 24 Aug 2003

John, part of the reason why I posted that note to the plugin developers was to see if anyone else had any ideas on how to do just that. smile

I wish there was an easy way to do this. At the moment, the name "SessionPlugin" is hard-coded into BeijingRelease as the only plugin that is allowed to handle sessions. This was meant to fix a bug, and I imagine in CairoRelease this restriction might be lifted, but I'm not counting on it.

The way in which TigerSkinPlugin and GnuSkinPlugin (and some others similar to those) determine whether or not to use SessionPlugin extensions is that they look for the TWiki web TOPIC "SessionPlugin".

Now, because "SmartSessionPlugin" must be named "SessionPlugin" in order to work with the core TWiki code as a session-handling plugin, I cannot simply rename the plugin. However, I suppose a user could COPY data/TWiki/SessionPlugin.txt* to data/TWiki/SmartSessionPlugin.txt* (or symlink both the topic and the ,v RCS file to "Smart" versions). This would make it so that plugins could look for the topic "SmartSessionPlugin" FIRST and then look for "SessionPlugin." Meanwhile, TWiki wouldn't be confused by multiple plugins because only one "SessionPlugin" would be found within the lib/TWiki/Plugins directory.

That really seems like a bad hack though. I'm not sure if I would want to start some sort of precedent for that type of operation. That makes installation much more complicated too.

Really, I wish there was some way for a plugin to identify itself, if it exists, via some new handler. I would like to see some sort of function that would get a plugin version from a named plugin, and if the plugin wasn't active, then would return undefined. Perhaps the default operation would be to look for a handler within each plugin to handle returning the information from the plugin, and if that handler wasn't found, simply try to return the $VERSION from the plugin. If neither of those were not found OR if the pluginw as not found, then return undefined.

This sort of function would allow other plugins to see what other plugins were loaded and what version they were.

I've added a request for such a function to AddPluginIdentifierHandler. More details are given there as to how this function would operate and what it would return.

Any other ideas on how to separate one SessionPlugin from the other right now without modifications to TWiki code? Should I alter the SmartSessionPlugin.tgz distribution so it includes both a "SessionPlugin.txt" and a "SmartSessionPlugin.txt" that are identical copies of each other? (that seems like a really messy nightmarish hack)

-- TedPavlic - 25 Aug 2003

How to know which brand of SessionPlugin is installed? Until core plugin API provides function for that, we could have variable SESSION_BRAND or something. It's simple - will it help?

-- PeterMasiar - 25 Aug 2003

Well, in a way this already exists.

If a Plugin developer currently wants to check, he or she should query $TWiki::Plugins::SessionPlugin::VERSION and make sure it's greater than or equal to version 2.120, for example.

I picture something like:

if( defined( $TWiki::Plugins::SessionPlugin::VERSION ) )
{
    if( $TWiki::Plugins::SessionPlugin::VERSION >= 2.120 )
    {
        # This is SmartSessionPlugin
    }
    else
    {
        # This is basically SessionPlugin
    }
}

I suppose that's not horribly ugly, though it isn't really good [OO] programming practice...

So I guess that's the easy answer.

-- TedPavlic - 25 Aug 2003

I just wonder if it's worth it for skin developers to make a difference. If you already have to do it the "old fashioned" way with SessionPlugin, do you really gain anything from also using a feature of SmartSessionPlugin?

I think the gains from using SmartSessionPlugin probably come more with people who know it is installed and are willing to assume it's always going to be installed. That allows them to put the SmartSessionPlugin tags in their more static pages, like their TWiki pages and TWiki templates.

Plugin developers have a lot more flexibility because they work with code directly. That being said, as long as they know ONE of those is installed, they don't really gain from specializing (at least not yet?) as most of the gains in SmartSessionPlugin are either transparent and hidden from everyone (session gains) or added for the ease of those who are using an interface that is NOT code.

-- TedPavlic - 25 Aug 2003

Note that the fix that will soon be available for InitializeUserHandlerBroken will allow for session plugins that are NOT called "SessionPlugin". That means that SmartSessionPlugin will actually be able to be called SmartSessionPlugin. smile When this occurs, checking for the existence of "SmartSessionPlugin" as a TWiki topic will be sufficient (assuming it's at least version 2.120, which is a good number to call the "real" final release with all of the new features added)

-- TedPavlic - 26 Aug 2003

CGI::Session is mentioned on the SmartSessionPlugin page under the technology heading, but I didn't realize that I needed to load that CPAN package. I figured that the requirements for SmartSessionPlugin would be the same as for SessionPlugin. The Plugin install section should say that you need to install CGI:Session since CGI::Session.

-- JohnRouillard - 31 Aug 2003

More MOD_PERL issues (also speedy cgi et al)

I tried to bring up the SmartSessionPlugin under mod_perl. It acts very wierd. I am using the gnu skin and I can refresh my browser and end up with "login>>" displayed where my username was before I refreshed. I have authenticaed both using the login>> link and by editing. Both modes of authenticating will loose the session. When I get the logon>> displayed again, I can hit edit and get the edit window immediately.

Ted's comments about the problem are parraphrased from above in italics.

First, some explanation for what _init_authuser does:

  1. If already run, return true immediately.
    • Otherwise, remember that it is being run currently so that next time it is called within this instance, it will return immediately.

This I think is the crux of the problem. There is only one instance of the script when running under persistant perl execution environment like speedycgi or mod_perl. So this ends up caching the authentication info of the first user to use it on a given apache (httpd) execution. Anybody who subsequently connects to that server will get the same session info hence the flipping between login>> and JohnRouillard in the gnu skin.

  1. Next, use CGI::Session . . .
    • to get a cookie or a CGI session variable from the user identifying their session
    • if the user has identified a session . . .
      • find that session on disk and load it into memory *can we do a call to _init_authuser here?*
      • if that session's stored username or IP address does not match current user, then clear the session and start a new one

Tht explains why the session id keep flopping. I connect to an apache instance that has _init_authuser run as guest so, it gets my session keys sees that I am not guest, and starts a new session as guest.

If we run init_authuser where I indicate in bold, will that work? It's critical that the user be authenticated again on every connection. You can't assume that a connection is the same as a new execution environment.

I tried short circuiting _init_authuser by setting the variable $done_init_authuser to 0, but that really flaked things out. SESSION% stuff started showing up in the gnu skin as though the plugin wasn't replacing the substituted values. Hardly surprising 8-).

[...] And that's it. It's fairly simple. But CAN it be fixed within SmartSessionPlugin? I am not convinced it can.

Maybe not, but so far SessionPlugin seems to work under modperl. I really will be able to tell tomorrow when my co-workers come back to work.

-- JohnRouillard - 01 Sep 2003

In a side conversation over e-mail about some differences between SessionPlugin and SmartSessionPlugin, I've thought about doing two things:

  1. Bringing out a version of SmartSessionPlugin that has the ability to disable defaulting to Apache "Basic Authentication" as the #1 priority type of authentication. This would make it so that if nothing was stored in the session variable "AUTHUSER," the plugin would assume no one has authenticated. This would put the burden of setting "AUTHUSER" elsewhere.

  1. Bringing out a new plugin that simply looks for $query->remote_user and sets the session variable "AUTHUSER" to it when it is found. This would work with both SessionPlugin and SmartSessionPlugin to make session-persistent authentication work with "Apache Basic Authentication" that is used throughout many TWiki webs. Combining #1 and #2 would thus give the same functionality as the current SmartSessionPlugin, which isn't important, and extends SessionPlugin, which is a secondary concern. The real purpose of doing #2 is to show a proof of concept that SessionPlugin and SmartSessionPlugin can easily be extended to other types of autentication.

Now, in order to do this, this would require SmartSessionPlugin to allow SetSessionVariable to play with the AUTHUSER variable. Currently, this is hard-wired so that SetSessionVariable cannot play with that authentication token. The reason for this is that the new version of SmartSessionPlugin allows session variables to be get and set directly with TWiki variables. This makes it easy for someone to immediately "set" their own authenticated user name. (these session variables can also be messed with with CGI parameters)

So I guess the thoughts I was having are:

  • Should SmartSessionPlugin allow for TWiki variables to set and clear session variables directly? Is this extremely useful? It seems useful in the CGI context with CGI parameters especially. However, it then makes it so that AUTHUSER must be hard-wired to NOT be toyed with within SetSessionValue

  • Perhaps the TWiki core should have a "setUserName" function which could be implemented within SmartSessionPlugin that would allow for that AUTHUSER to be set from within a plugin but not from TWiki directly. This would require changes to teh TWiki core.

Does anyone have any thoughts on this? I'm going to start a AddingASetUserNameFunc topic for further discussion of this.

-- TedPavlic - 02 Sep 2003

John, regarding your comments about CGI::Session...

  • I listed "CGI::Session" as required under the "CPAN Dependencies" section at the end of the plugin topic. This "CPAN Dependencies" section seemed to be standard to all the other plugin pages, so I figured that was enough. I can add a section to the installation instructions that makes sure the user remembers to install CGI::Session.

John, regarding your comments about modperl and such... (the problem is fixable; I just fixed it by commenting out about 3 lines of code and adding 2; but I don't like the fix -- this is a problem with the TWiki core)

  • SessionPlugin suffers the same problems as SmartSessionPlugin, but SessionPlugin differs in how it does authentication (where in most cases it doesn't do authentication at all). The reason why your simple settings are being maintained in SessionPlugin but not in SmartSessionPlugin are because SmartSessionPlugin clears its session data every time it thinks it's getting a new session ID. SessionPlugin simply DOESN'T NOTICE it get a new session ID.
    • To demonstrate this, look at SessionPlugin's sub _init. You'll see that it, like SmartSessionPlugin, will only run once ever. You'll also find that it's the thing that sets the session ID. Once SessionPlugin is loaded, it assumes the same session ID forever. Everyone who connects to the website gets the same session ID. Yeah, session information stays persistent, but it becomes shared between everyone.

  • The problem actually is centered around the fact that the subroutine initializeUserHandler must be prepared to return something meaningful before initPlugin is called. That is, user information is already decided before any plugins are initialized. This is precisely the reason why _init_authuser (and _init in SessionPlugin) are called so early.

  • To fix this problem in SmartSessionPlugin, it's easy. Just:
    1. Comment out all calls to _init_globals and _init_authuser (should only be 2 or 3)
    2. Add a call to _init_globals and then _init_authuser in sub initializeUserHandler before teh return statement.

So supposively in CairoRelease, this bug will be fixed. When it is fixed, then it would make sense to go back to a more sane way of initializing all of this session stuff, and I anticipate that will make SpeedyCGI stuff work again.

In the meanwhile, is it worth doing such a hack as mentioned above?

If you think it is, I can upload a version of this plugin that works with SpeedyCGI. Please verify that commenting those lines and adding those lines fixes the problem. The point of the fix is to run everything in "initializeUserHandler" because that function is only called ONCE per page and is called earlier than everything else. It may be useful to put other things in there too that initialize other parts of the plugin, but all of this really belongs in sub initPlugin. It just can't be located there due to that bug.

-- TedPavlic - 02 Sep 2003

Edit | Attach | Watch | Print version | History: r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r2 - 2004-11-20 - MartinCleaver
 
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.