External Authentication

Discussion corner for Developers of Serendipity.
rrichards_
Regular
Posts: 28
Joined: Fri Jan 12, 2007 1:20 am

External Authentication

Post by rrichards_ »

I have been working on a plugin for authenticating with InfoCards and finally got it working with only a minor addition and change to the serendipity code. Is it possible to have these implemented?

The first request is to increase the username field to 32 chars in the authors table. The fields in the Authors table really have no meaning to the external authentication scheme, but it allows external tokens to be associated with author records so that preferences and even administrative permissions can be associated with the user. I used many of these fields for the association between the token and author record. Similar could be done with OpenID I would assume.

The next is the need for an additional event hook. I used 'backend_login' for now but have no qualms about a different name. This allows a plugin to perform authentication and setup the serendipity environment without continuing to the remaining code that performs the username/password checks. The code I propose is the following diff. This is a diff against the functions_config.inc.php released with 1.1. I was unable to access the SVN repository to make a patch against that.

--- functions_config.inc.php.org 2006-11-30 16:34:29.000000000 -0500
+++ functions_config.inc.php 2007-01-11 19:05:52.000000000 -0500
@@ -460,6 +460,12 @@
$is_md5 = true;
}

+ $is_authenticated = false;
+ serendipity_plugin_api::hook_event('backend_login', $is_authenticated, NULL);
+ if ($is_authenticated) {
+ return true;
+ }
+
if ($username != '') {
if ($use_external) {
serendipity_plugin_api::hook_event('backend_auth', $is_md5, array('username' => $username, 'password' => $password));
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: External Authentication

Post by garvinhicking »

Hi!

Increasing the username field is no problem, I've just done that to 1.2-alpha2.

The next one is complicated. I would have committed that a long time ago, but it wouldn't work the way as intended.

The problem is this: The first hook_event() call in the whole page flow will trigger Serendipity including all event plugins. Triggering including all event plugins will fix them at the language that the pageflow is currently at.

The language is only set to the proper user language once an author has been identified; else it will remain english. So this is why you might not have noticed the change.

As soon as we use a plugin API call *before* authentication (which your patch would do) we would be fixed at the english language, so I sadly cannot commit this piece of code.

Personally, I also cannot offer another choice, because none has yet come to my mind - I can't find a solution to our problem on my own, so maybe with your help we could work something out?

The first step might be for you to try what happens if you use a language like german or spanish, or whatever you might basically understand to test it with? :)

I'd really, really love to get this to work, but I'm afraid the execution flow of the plugin API might make problems there.

But, I'm also open to include code to the core of serendipity that deals with foreign authentication. OpenID has been on our scope a long time; if we can support it in core, all the better...?

Best regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
rrichards_
Regular
Posts: 28
Joined: Fri Jan 12, 2007 1:20 am

Post by rrichards_ »

First off thanks for the field size change.

I don't see the problem you are describing here, so let me know if the following is not what you were explaining.

First Test:
I set the language for the user authenticating externally to French. I then went to login and logged in with my InfoCard. Initially everything was English since no language was set. Upon authentication, everything switched to French like it should.

Next Test:
I created another user and set their language to French. I logged in a again, but this time it was done via username/password so the plugin would be executed but not authenticate. The user was authenticated by the default logic and the language still was correctly set to French.

Due to what the plugin is doing, I see it mandatory that the plugin set the serendipity environment correctly including calling serendipity_load_configuration().

Please correct me if you see anything wrong in the above logic.
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

Hi!

Thanks for doing these tests! I might have confused your patch with what I tried out previously.

However, this change is still something that might very easily break Serendipity's operation, so I will need to perform some tests. I'm quite swamped with work until the end of next week, but I'd love to test your patch the week after next and then check it thorougly, if you can wait that long and will then be around still for questions? :-)

I'd love to get this one off the ground, I think it's vital to the future of Serendipity. Maybe even the most vital part that currently is in development, apart from multi-blogs ;)

Best regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
mattsches
Regular
Posts: 440
Joined: Sat Nov 05, 2005 9:35 pm
Location: Wiesbaden, Germany
Contact:

Post by mattsches »

garvinhicking wrote:I'd love to get this one off the ground, I think it's vital to the future of Serendipity. Maybe even the most vital part that currently is in development, apart from multi-blogs ;)
I agree with you, Garvin, this is very important. And it's great to see someone develop a plugin for these new authentication mechanisms, rrichards_!

Once we got a working implementation InfoCard, it should not be too difficult to add other services like OpenID. I've just been thinking of playing around with this OpenID lib a little over the weekend ... but now I'll just wait a little until I can take a look at the InfoCard solution, I guess :D
rrichards_
Regular
Posts: 28
Joined: Fri Jan 12, 2007 1:20 am

Post by rrichards_ »

garvinhicking wrote: However, this change is still something that might very easily break Serendipity's operation, so I will need to perform some tests. I'm quite swamped with work until the end of next week, but I'd love to test your patch the week after next and then check it thorougly, if you can wait that long and will then be around still for questions? :-)
I am typically around, though sometimes slow in answering.

Off the bat I am trying to make the least amounts of changes within the core serendipity code since the identity technologies are still evolving, yet having it flexible enough that different ones can be integrated. Looking at the hook, it would probably be better to pass an array instead of the $is_authenticated var though so it can be a bit more flexible on the data passed back and forth. At least with a new event type, it wont break anything since no one is currently using it :).

There may be some things that need to be worked out in the multi-blog scenario (I am not too sure of that workflow). I notice that the logon routines are called quite a number of times. I basically set a session flag if the user authenticated with an inforcard and when the logon routine is called again and serendipityAuthedUser is true, if they have my session flag set then I consider them still logged in so re-setup the serendipity vars from my session vars and return a TRUE to indicate they authenticated.

A combination of the external ldap and adduser plugins was used for the basis of the code, so the workflows are similar in a manner. Anyone interested in seeing an early implementation I did can try it out at http://www.cdatazone.org/ . This was prior to any work i did on an actual plugin so what you see there is actually a hacked up version of serendipity, ldap plugin and adduser plugin. Having some server issues right now so it may be up and down at times, but I will try to post my current code when I have a chance.

Rob
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

Hi rrichards_!

I now checked the patch. The problem is that if you call the plugin API hook your way, the event plugins will be loaded with english language. Only the core language will remain as you select, but not the individual plugins. Note that sidebar plugins are loaded later (because they do not interact with the framework, they don't need to be initialized earlier on), and thus show up with the right language.

You can see that if you set the default blog language to english, and your personal language to german. The plugin descriptions will then all be in english, and not in german.

This happens, because in serendipity_config.inc.php the lang.inc.php file is included AFTER the serendipity_login() function, and that means the final visitor language is only available after the login function.

Plugin languages are loaded on call-time though as soon as the first plugin API call is made.

If we shift the serendipity_login() function after the login call we'll have the problem that the language would always be fixated on the default language instead of the personal.

Our problem is that languages cannot be "reloaded" (they are constants). And even if it were variable based, it would somehow suck that all language files would need re-iterating.

Sadly, at the first plugin API call we need to load ALL installed event plugins, because only then we can find out which plugins are registered to which hooks.

Thus, I believe the only way to get this to work is to find some other way of supporting foreign authentication. Any proposals? Maybe put the functionality into the core serendipity pack?

Another way that comes to my mind is to create one other type of plugins, like event and sidebar plugins. Those plugins could be loaded before language fixation. But then, this would mean more API overhead and one more section in the plugin manager - just for the sake of very few plugins who require this.

So, I'm in favor of putting it in core. :-)

Best regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
rrichards_
Regular
Posts: 28
Joined: Fri Jan 12, 2007 1:20 am

Post by rrichards_ »

I went through more of the core code and now see and understand the problem you were initially talking about.

This being said, I still think trying to do excessive integration with the core code is a bad idea. The problem I see is that foreign/external authentication can be done is so many different ways, I don't think it could really be done and remain flexible enough to be able to provide universal support for all current and future mechanisms. In many cases not only the workflows will be different, but also the authentication information and packaing of the information will/can be extremely different.

Now, although you can tell my feelings on tight integration, there is an existing option I know of, though have not looked at it in depth, that does provide i-card, openid and infocard authentication and could possibly be used for a core integration. Whobar: http://whobar.org/. Again, I just want to re-iterate that this potentially locks authentication into only thoe supported.

As for other options/ideas:
- why cant the default language be retrieve from some other mechanism (session/cookie/etc..). If the user had already logged on then their id is captured so that their preferences can be retrieved. Now, why not also capture the language too? This way in the event the code enters the section where it assigns the default language for the user, it can first check if there is one stored (same place where author id is stored) and use that language. If none is found then fall back to default language. This *should* pretty much fix the language issue as far as i can tell.

- the other option is to do exactly what you mentioned. I don't think the additional overhead would be that much. You are correct that it would create an extra section, but possibly there might be some other use for being able to load a plugin prior to a login which could also fall into this area (probably not but possible).

I would strongly discourage baking this stuff into core just for the fact that it is possible that a year or so from now all of these authentication technologies could prove to be complete crap and something completely different is being used. By just providing some type of hook allows developers and end users to be more nimble for change. Just one man's opinion though.

Rob
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

Hi!

I believe the way to store the user language in a cookie and the sesion is the way to go.

We need then to ensure that when the autor_information cookie is saved, the current language of the user also needs to be saved. When a user updates his configuration, the new language needs to be saved (in both cookie AND session).

The only problem I'm seeing is that these changes might make problems with the multilingual event plugin which allows visitors of a blog to change the language. This is usually checked via serendipity_getSessionLanguage(), so we need to make sure that this function is called before the first plugin API hook.

Also it needs to be checked that fetching the blogs current language ($serendipity['lang']) is loaded BEFORE the first API hook, because this is the real language that should take precedence if no user-configured language is present in session or cookie. But I think that the $serendipity config array is fetched pretty early, before the login procedure.

As last thing, the cookie/Session language data needs to be validated so that it can only contain a valid string present in the $serendipity['languages'] array.

So. Uhm. You're not supposed to want to have a stab at that? :-) :-)

Best regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
rrichards_
Regular
Posts: 28
Joined: Fri Jan 12, 2007 1:20 am

Post by rrichards_ »

I was hoping you were going to say that :) To me, at least, it looked like a pretty decent solution.

I'll take a stab at making these mods. I've looked through the code a bit so have a pretty good idea what needs to be done. Will need a little time to do this though.

Rob
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

Hi!

Awesome! Take your time. I'd love to have done it already, but my time schedule is pretty loadde at the moment, and there are still some s9y related bugs stacked up that I need to look at.

Please ask me any questions you might face along the way. Your help is much appreciated. :-)

Best regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
rrichards_
Regular
Posts: 28
Joined: Fri Jan 12, 2007 1:20 am

Post by rrichards_ »

After some additional testing strictly with the latest code, I am running into an issue introduced in 1.1.

http://svn.berlios.de/viewcvs/serendipi ... 09&r2=1425

This now makes it impossible to operate in a mixed environment. Prior to this, it was possible to force all logins to go through SSL to secure credentials. The user then was free to post comments on the site without having to use a captcha because they are currently logged in. Now they must access the entire site via SSL once they haved logged in to have their preferences and logged in state recognized.

Is there some way to make that change optional based on configuration somehow or even just require the site admin to change their ini file for the secure cookie setting (though I dont think they can work around the session name piece)?

Rob
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

Hi!

Do you know what exactly leads to the mixed environment no longer functioning? Is it the 'cookie_secure' setting?

Because usually http:// and https:// do not share the same session, so I don't see how it could have worked previously?

Best regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
rrichards_
Regular
Posts: 28
Joined: Fri Jan 12, 2007 1:20 am

Post by rrichards_ »

There are actually a couple of problems. The first is that they no longer share the same session because when under HTTPS, it uses a different session name (SSLSID - set by the first ini_set call). Prior to this the same session is used for http and https. Not sure why you are under the impression that they dont typically share same session.

I went ahead and removed that call, which allowed the use of the same session. Next problem depends upon whether the session is initiated from HTTP or HTTPS.

If the user navigtes to the HTTP site first, then everything is ok as the session cookie is set and allowed for all types of connections.

If the user navigates to the HTTPS site first then the session cookie is set for only secure connections (the secure_cookie setting). They then navigate to the HTTP site and since the session cookie is prohibited from being sent, a new session is generated (this time an any connection type cookie), previous session cookie overwritten causing previous session data is lost. The user then needs to re-logon again which will now work since the session was generated un-restricted.

Rob
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Post by garvinhicking »

Hi rob!

Ah, now I understand the problem.

Sigh. I wish it were easily configurable, but at that point in the code, it isn't yet and I'm afraid it would introduce some borkage if I move the session_start() much later in queue after all initializing is done. This would mean for some plugins and pieces of the code to have no access to $_SESSION.

The use of that function could be fixed at an $_ENV variable be present maybe...?

The reason for this code intrudiction was to forcible have a distinct HTTPS session, so that a cookie never gets set unencrypted. So this defeinitely has an upside which we can't simply neglect and turn to the old behaviour again.

Maybe we could use ini_get() for some configuration checks to see if that behaviour is wanted, what do you think?

Best regards,
Garvin
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
Post Reply