Tags:
create new tag
, view all tags

Adding a setUserName Function to Func API

In a subject I brought up in SmartSessionPluginDev, I suggested that perhaps a "setUserName" function should be added to the Plugin API. (or perhaps a "setSessionUserName" -- to go along side "setSessionValue" and "getSessionValue" (and perhaps "clearSessionValue" as proposed in AddClearSessionValue))

Here's the motivation:

  • I claim that session plugins should give full access to session variables to all aspects of TWiki. This allows all TWiki users (not just TWiki plugin developers) to use session variable space as a "session persistent storage" for values to be passed from one page to another during a session.

  • If this is the case, not only should session variables be more securely managed (see bug SessionVariablesOverrideFinalPreferences), but the session variable that holds authentication information should only be toyed with by plugins. It should not be accessable to TWiki users.

  • It seems wrong to restrict getSessionValue and setSessionValue to plugins. However, plugins do need something for authentication just for them. This way a plugin can implement a new type of authentication (or work with an existing type) and use SmartSessionPlugin as a way of remembering that the user was authenticated.

  • So the idea is to create a setSessionUserName or setUserName that a plugin can call to set the session variable for the user name. A "setSessionUserNameHandler" inside the session implementing plugin that would set the session username variable to whatever was passed to it.

I don't think this is getting too complicated, namely because:

  • Session variables should be available for easy access.

  • Authentication is a very special-purpose use of sessions that needs more delicate handling.

Any thoughts? This would be an easy add to the API.

-- TedPavlic - 02 Sep 2003

A clearUserName or clearSessionUserName function would be nice too for authentication methods that have a "logout."

-- TedPavlic - 03 Sep 2003

It would be useful to see some use cases for how this would work, i.e. specific sequences of user login, plugin activation, etc. It is useful to have a specific API to set user name etc, to enable various authentication schemes, but I need to see some examples of what can and can't be done with this.

-- RichardDonkin - 03 Sep 2003

User can be set by return value of initializeUserHandler. At present used by SessionPlugin to preserve the user (e.g. when on non-authenicated pages) or could be used (as I believe another plugin does) to auto login based on a persistant cookie. I'm not sure what unsetting a user would mean or the side effects of changing the user after plugin and preference initialisation. i.e. I can't see how such functions could work.

Now logging out is an interesting point, but if logged into session, then session plugin can surely end the session, maybe a hook for this is required.

-- JohnTalintyre - 03 Sep 2003

A simple example:

Imagine that someone had SessionPlugin installed. This plugin provides an interface to other plugins to use setSessionValue to set a session variable "user". When this session variable "user" is set, SessionPlugin's initializeUserHandler returns that session value to TWiki indicating that a user has logged in. This allows logons to be preserved on pages that do not require authentication, like view).

Now, that same user has some authentication scheme. For example, that user is using Apache's "Basic Authentication" or has a logon script somewhere else based on LDAP authentication or something similar. Once authenticated, by way of the modulates included from lib/TWiki, the user calls setSessionValue and sets "user" to the authenitcated user name returned from whatever authentication scheme they use.

Now that "user" is set, TWiki remembers that that user is logged in throughout the entire duration of that session.

That entire example was done with SessionPlugin and the setSessionValue function that is already provided by TWiki. Now, there does not appear to be any way to easily "logout." setSessionValue could be called again to set "user" to an empty value, but having a way to clear that session variable seems to be more appropriate. That is, imagine the user was able to clearSessionValue; this would log them out and allow someone else to logon, as long as the authentication scheme made that possible. The proposal to add a clearSessionValue is discussed in AddClearSessionValue.

The need for a setUserName type function comes when session variables are opened up directly to users. The motivation for this example comes from the existance of SmartSessionPlugin that, as of version 2.120, allows TWiki users to directly set session variables without the aid of a frontend plugin. That is, a user can either use a TWiki variable or a CGI parameter to set a session variable while viewing a page. This, of course, causes a security risk. A user could simply set the "user" variable mentioned in the last example without even authenticating.

So in SmartSessionPlugin, users are specifically not allowed to set or clear the session variable responsible for persistent logons. That is, the session variable "user" is protected. This is implemented by putting a check in the setSessionValueHandler function that causes the function to return immediately if "user" is the requested session variable. This means that the only plugin that can EVER touch the "user" session variable is SmartSessionPlugin.

And so it is not possible to repeat the above example with SmartSessionPlugin because of restrictions within SmartSessionPlugin. If a function setUserName or setSessionUserName was added and implemented with SmartSessionPlugin, then other plugins would now be able to implement the above example and the "user" session variable would still be securely protected by SmartSessionPlugin.

The other solution to this problem is to change the implementation of SmartSessionPlugin so that it still allows setSessionValue to be called on "user," but will not call setSessionValue if a CGI parameter or a TWiki variable is the caller trying to set "user." This would:

  • Still protect "user" from misuse of TWiki variables and CGI parameters.
  • Still allow plugins to set "user" as they please
  • ASSUMES that plugins are able to "know" what the authenticated user session variable name is (I have been using "user" thus far)

That last bullet identifies the complication with relying on setSessionValue to set the authenticated user name. SmartSessionPlugin gives users the option to change that authenticated user session variable name. For example, on my TWiki system it is "AUTHUSER" rather than "user." This is desirable as users may have another intention for the session variable name "user" or something along those lines. However, there is no way for a plugin to know what the current authenticated user name is without probing around variables contained within the SmartSessionPlugin namespace.

So I'm proposing to add functions like:

  • setSessionUserValue (takes one parameter: a user name)
  • clearSessionUserValue (takes no parameters)

that would set and clear the internal session user name that is used by initializeUserHandler. (of course, they would be implemented within SmartSessionPlugin as Handlers) These functions would only be called by plugins, and specifically would be called by plugins whose sole purpose was to authenticate users. SmartSessionPlugin would then take on the burden of making sure they stayed authenticated.

Note that SmartSessionPlugin currently doubles as an authentication plugin that passes Apache's "Basic Authentication" username on as needed, but there's no reason why an "ApacheAuthenticationPlugin" couldn't be written that did exactly what was mentioned in the example above.

Is this a sufficient example?

-- TedPavlic - 03 Sep 2003

Ted, not sure that you've answered my points above. Would be great if you could be a bit more concise. I note you say "These functions would only be called by plugins". But, by the time other plugins are initialized it is too late to change the user. To be honest, when we added this capability into TWiki we did it by trial and error, it took time to get through my thick skull that user initialisation had to happen before existing plugin functionality cut in.

A bit different for logging out, but as I say above, isn't this more a question of ending the session? Mind you, if http basic authenication is in place how do you stop from being logged in again (automatically) as soon as you go to an authenicated page like edit?

-- JohnTalintyre - 04 Sep 2003

John, I think you misunderstand the point of this function. It is not meant to replace the initializeUserHandler. Re-read my example. You'll see that all this function would do is record the current state of the username to a cookie (or a "session," more accurately).

Currently SmartSessionPlugin does this automatically. The first time it sees $query->remote_user, it fills in the "AUTHUSER" session variable. Later, if it doesn't see $query->remote_user but it DOES see $session{AUTHUSER}, then it returns $session{AUTHUSER} from initializeUserHandler. Of course, this has to happen before plugins are initialized.

But the setUserSessionName function would do the EXACT same thing as setSessionValue. Really, as is currently written:

setUserSessionName( "tpavlic" );

would be the same as

setSessionValue( "AUTHUSER", "tpavlic" );

The trouble with only having setSessionValue is that other plugins have no way to know what the first parameter should be. That is, should they access "AUTHUSER" or "user" or "someOtherSessionVariable" ? Plus, SmartSessionPlugin at the MOMENT does not allow the setting of "AUTHUSER" for security reasons. There are other ways this can be implemented, but that's just how it currently is implemented. Those are sort of "prototype semantics" that I'm trying to hash out here.

So what I'm proposing is just a way to save to the session the username so that it can be retrieved later. One solution to this problem would be to deem a particular preference (call it "WIKIUSERNAME" or something) the user's name. If this preference is filled, then set the username to this. This would remove the need for initializeUserHandler. When TWiki queried the username, it could first look at the "WIKIUSERNAME" preference and if it was set, use that username. Now, when it queried it, it would first look to the session. If there was a session variable called "WIKIUSERNAME" then it would use that. Then:

setSessionValue( "WIKIUSERNAME", "tpavlic" );

would be enough to record that "tpavlic" logged in and would make that logon persistent. Of course, there are still start-up problems; sessions would have to be initialized before the username was queried, so you run into the same problems that you have with initializeUserHandler, but this is just an example to try to demonstrate what setUserName does.

So in summary:

  • setUserName would not replace initializeUserHandler

  • setUserName is not meant to actually log a user in

  • setUserName just records a user name to a session in a special well-defined place that initializeUserHandler knows about

  • initializeUserHandler is the only thing that needs to be run early, and it has access to the session location that setUserName writes to

Having these available allows for lots of pluggable authentication modules to call "setUserName." In most cases, it wouldn't be important that setUserName happens so late becuase the thing that TRIGGERS it has already authenticated. You could then have modules like:

  • ApacheBasicAuthenticationPlugin - constantly looks for $query->remote_user and when found, writes it with setUserName to a session. It's not important that this write happens so late, as $query->remote_user was set really early and is the dominant authority on authentication. When the user leaves an authenticated page, the session variable just written takes over on non-authenticated pages.

  • Some form of LDAP authentication - an LDAP frontend that is not related to TWiki includes TWiki.pm. After it authenticates, it calls setUserName and then REDIRECTS to TWiki. TWiki then looks at the session, sees the username, and keeps teh authenticated user.

  • Other forms of authentication would be similar - call setUserName from TWiki.pm and then redirect to the actual TWiki page

Regarding logging out, this would be dependent upon the type of authentication. Of course, "Apache Basic Authentication" has NO WAY to log out, but the LDAP autehntication method would just have to clear the session, as would other forms of authentication.

Does that make more sense? It doesn't matter that setUserName happens so late as its purpose is not to actually do the authentication. It's purpose is just to add memory -- it is a way for other plugins and modules to REMEMBER that authentication happened by way of the session. This could already be done with setSessionValue, but other plugins would not know which session variable to write. (and it's questionable as to whether other plugins should have access to that very special variable)

-- TedPavlic - 04 Sep 2003

I suspect I'm missing something here, I'd have thought a plugin wanting to do this would implement initializeUserHandler and possibly other plugins functions. That's what we do at DrKW for our LDAP authenication. I guess you're saying this muddle sessions capability with logon. But, it seems odd to me to have a new method so one plugin can pass on setting the user to another, when the first could in any case use the provided function and get logon during this http call, rather than on the next one.

-- JohnTalintyre - 05 Sep 2003

I'm not sure I understand your response. To summarize what I'm talking about, starting from a bare bones TWiki installation without session support...

  • The TWiki website recognizes that a user is logged in on an AuthenticatedMode page
  • The TWiki website thinks that TWikiGuest is logged in on all NonAuthenticatedMode pages (assume $doRememberRemoteUser is off)

So then we add sessions:

  • The TWiki website recognizes that a user is logged in on an AuthenticatdMode page
  • The TWiki website recognizes the user is logged on whenever a session variable ("user" or "AUTHUSER") is set to a valid username
  • The TWiki website thinks that TWikiGuest is logged in on all NonAuthenticatedMode pages when that session variable is empty

This requires the session plugin to:

  • Provide an implementation for setSessionValue
  • Allow for a call to something like setSessionValue( "AUTHUSER", "tpavlic" )

The problem is:

  • The session variable "AUTHUSER" is not set in stone. It could be configured to be "user" or something entirely different. It seems silly to force the user to set that particular session variable.
  • Allowing setSessionValue to access that session authentication variable directly may open up a little bit of a security hole.
    • A session plugin (like SmartSessionPlugin) may allow a TWiki user (not a plugin, but an actual user) to access session variables directly
    • If the user can access session variables directly by way of TWiki variables or CGI parameters, the user now can access "AUTHUSER" directly

Solutions to these problems would be to...

  • Allow setSessionValue to play with the session authentication variable ("AUTHUSER" or "user") but do not allow setSessionValue to be called from TWiki variables or CGI parameters in the case where the variable that they are trying to access is "AUTHUSER" or "user" or whatever the session variable is
  • Restrict setSessionValue to session variables other than "AUTHUSER" or "user" and create a new method setSessionUserName that only takes ONE parameter
    • This makes setSessionValue entirely safe as it will never be able to play with the session variable directly
    • This allows other plugins the ability to set the session username without having to know what the session authentication variable is

I see no reason why all other plugins should have to know that the session variable name is "AUTHUSER" or "user." This "session authentication variable name" could be standardized, but . . .

  • If it is standardized to some very odd name like "sessionUserNameVariable123456789" then it's awkward to see in other plugin code
  • If it is standardized to some simply name like "user" then it starts to impede on the "session namespace" of other plugins
  • If all I want to do is set the username, it seems silly for me to have to worry about variable names and everything else. I simply want to set a username, so I should be able to pass in a username and expect it to be set. I shouldn't care about how or where it is set. Those details can be hidden by the setSessionUserName procedure.

Does that make it more clear what I'm trying to say? I'm assuming that on your DrKW the LDAP authentication module accesses the session directly and sets "user" to whatever the authenticated username is. This would make this simpler to implement in that:

  • The LDAP tool would not need to access the session directly ever
  • The LDAP tool would not need to know anything about the session variable name (i.e. "user" or "AUTHUSER")
  • The LDAP tool could make one call out to the session-handling plugin in TWiki and all of the implementation details would be hidden inside that session-handling plugin.

I view authentication to be a special-purpose use of sessions that requires special handling. I'm suggesting that setSessionUserName and clearSessionUserName are the functions which implement this special handling.

-- TedPavlic - 05 Sep 2003

Edit | Attach | Watch | Print version | History: r12 < r11 < r10 < r9 < r8 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r12 - 2008-08-14 - RafaelAlvarez
 
  • 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.