gluon.contrib.login_methods.CasAuth

85 views
Skip to first unread message

hcvst

unread,
Jul 29, 2009, 6:12:10 PM7/29/09
to web2py-users
Hi,

I am just trying to implement CasAuth to plug openID (oID) into auth
().
I've got a simple oID server/consumer app using the Janrain
Python oID lib.

The login_methods.gae example included in the login_methods folder
seems to fit (too) well, as all external calls are wrapped nicely in
the
gae lib, but I am struggling to see how to do the same with my oID.


Here's what I've tried now. It works.. just.

1 - Pack all oID functionality into a module and place it in
myapp/modules
.../modules/w2popenid.py ( http://pastebin.co.za/23469 )


2 - the module provides an oID service a bit like Auth such
that it can be served via a single controller function.

consumer_service = w2popenid.Consumer(env, db)
def oid_consumer(): return (form=consumer_service())


3 - in db.py, I set auth.settings.login_form (or so) to

from app.modules.w2popenid import OpenIDAuth
auth.settings.login_form = OpenIDAuth(service_url, globals())

where
OpenIDAuth implements/extends the class CasAuth
and service_url : URL(...f='oid_consumer')
is the url of the controller function bound to consumer_ service
in 2. above so that CasAuth.login_url can provide the service URL,
when asked by auth.

Then it's a back and forth between controller, openID provider
and OpenIDAuth, with all required data stored somewhere in session.

Is that how one should plug sth like oid into auth()?


If that is the correct approch, there are some other issues:
For example if oid_consumer() is defined outside the default
controller,
auth() seems to get mixed up and redirects to the default controller.
Also, I don't seem to be able to flash my status codes back via
session.flash
Finally I am not sure whether I have to extend the users table to
cater for
additional openID fields and how best to do this.
But these are issues to solve once I know I didn't misunderstand
login_methods..

If this doesn't make much sense. Please get me to the point tomorrow.
Time to say...

Good night,
HC

mdipierro

unread,
Aug 1, 2009, 6:54:20 PM8/1/09
to web2py-users
Sorry it took me so long. I looked into this and it cannot be done
this way easily as I though. The reason is that OID uses the two
tables you created (and you are correct) and does not use auth_user at
all. Hence it cannot take advantage of the functionality of Auth
(access control, etc etc.). Open id can only determine if a user is
logged in or not.

The best one can do is create a new OpenIDAuth class that replaces
Auth and exposes similar 'login', 'logout', 'require login'
functionality.

I think you did this already in the OpenID app.

Massimo

Bottiger

unread,
Aug 2, 2009, 1:09:42 AM8/2/09
to web2py-users
Massimo, are you saying that there will never be an official Web2Py
incorporation of OpenID and Auth?

hcvst

unread,
Aug 2, 2009, 6:59:22 AM8/2/09
to web2py-users
Hi Massimo,

thanks for your reply.

I had another look and don't think one has to necessarily reimplement
all
Auth functions. I think that the setup above works in principle, but
that there are
some inconsistencies within Auth one has to work around at the moment.
Let me summarize briefly.

The Module w2popenid.py has three classes.

1. class Consumer
Used in a controller (for ex: openid.py) as

def oid_consumer(): return dict(form=Consumer(globals(), db))

It understands the args 'login' to provide and process a login form
and
'oidresponse' to check the response from the oid provider upon
redirect
to the return_to_url by the same.


2. class OpenIDLogin
Extends gluon.contrib.login_methods.CasAuth and is used in a model

auth.settings.login_form = OpenIDLogin(globals(), URL(...))

where URL's c and f parameters are those of the oid_consumer in 1
above.
i.e. URL(r=request, c='openid', f='oid_consumer')

As per the interface it implements the methods:
login_url(self, next) - returns the URL passed to __init__ and sets up
oid session
logout_url(self, next) - destroys oid session and redirects to next
get_user() - if logged in returns a dic(username='..', email='...) -
it does not
yet but the SREG extension for OID allows one to fetch these.
I don't need to store these myself as auth.get_or_create_user handles
this
behind the scenes. In fact I do not even need to store the oid itself,
as
long as I can get hold of the email address.


3. class Web2pyStore
Handles storage of associations and nonces for the Janrain library.
Does not
store any user info.


It works. If you log on using your open ID, entries for that user are
created
in auth_users.

@auth.requires_login()
does not work as this method does not look at auth.settings.login_form
but only at auth.settings.login_url
Consequently the user is redirected to the wrong form.

Regards,
HC

hcvst

unread,
Aug 2, 2009, 7:07:48 AM8/2/09
to web2py-users
Comment to self really. OID has to be stored, as otherwise any
OID claiming to be associated with email address can access
that account.

mdipierro

unread,
Aug 2, 2009, 7:12:03 AM8/2/09
to web2py-users
No. I am just saying that saying that it will be easier to implement a
new class that extends Auth with OpenID, instead of creating a OpenID
plugin for Auth.
The interface will be the same so you do not need to change your code
but you need to change the line

auth=Auth(...)

to

auth=OpenIDAuth(...)

hcvst

unread,
Aug 2, 2009, 9:23:07 AM8/2/09
to web2py-users
Hi Massimo,

I like the plugin. Just three methods to implement and I do not not
need to know how
Auth works under the hood. In terms of maintenance this seems nice, as
it's quite
loosely coupled. Sure, when extending Auth, the user only has to
change Auth to OpenIDAuth
in the model, but that's only because the skeleton app now comes with
an auth controller
function. If you really prefer Auth to be extended, I'll give it a
try, but I would prefer to
see auth's plugin mechanism to work consistently (unless it does
already and I misunderstood
how to use it). I can post to the dev-group regarding the auth
'inconsistency' as I see it.

Regards,
HC

mdipierro

unread,
Aug 2, 2009, 9:24:38 AM8/2/09
to web2py-users
Let's think about this some more.

Massimo

hcvst

unread,
Aug 2, 2009, 10:03:15 AM8/2/09
to web2py-users
I agree. Also, OID should just be an alternative login method, with
the standard method always being available (unless disabled) too.

=HC

mdipierro

unread,
Aug 2, 2009, 10:18:52 AM8/2/09
to web2py-users
I see two problems that need to be solved and may require change in
Auth:

- all existing login methods use the same form (username/email
+password) but OID is different. So Auth must be able to delegate to
the login method form generation and processing
- OpenID does not necessarily return a first_name, last_name, email of
the user so there is not enough info to fill the database table
- when using OpenID some methods like retrieve_password should be
disabled or link the OpenID provider.

Massimo
Reply all
Reply to author
Forward
0 new messages