Auth is now always a cas service

123 views
Skip to first unread message

Massimo Di Pierro

unread,
May 23, 2011, 2:53:32 AM5/23/11
to web2py-users
With the code in trunk every web2py app is - by default - a CAS
service. To connect to from another app:

from gluon.contrib.login_methods.cas_auth import
CasAuth

auth.define_tables(username=True)

auth.settings.login_form=CasAuth(

globals(),
urlbase = "https://127.0.0.1:8000/otherapp/default/
user",

actions=['cas_login','cas_check','logout'])

Please help me test it.
Suggestions for improvement?

Massimo

Michele Comitini

unread,
May 23, 2011, 4:32:02 AM5/23/11
to web...@googlegroups.com
thanks Massimo that is cool!


2011/5/23 Massimo Di Pierro <massimo....@gmail.com>:

Massimo Di Pierro

unread,
May 23, 2011, 8:16:52 AM5/23/11
to web2py-users
I am not sure this should stay in the current form.

Should it be straight (compatible with) CAS?
Should we make it more powerful than regular CAS?
If so how?

Massimo

On May 23, 3:32 am, Michele Comitini <michele.comit...@gmail.com>
wrote:
> thanks Massimo that is cool!
>
> 2011/5/23 Massimo Di Pierro <massimo.dipie...@gmail.com>:

Ross Peoples

unread,
May 23, 2011, 8:24:41 AM5/23/11
to web...@googlegroups.com
I am not that familiar with CAS, but it might be useful in some cases to know what groups the user is a member of in the remote web2py installation. For example, if there is an 'Administrators' group that should have access to everything, then you wouldn't have to set up groups and permissions for every single app that uses the remote Auth service.

Massimo Di Pierro

unread,
May 23, 2011, 10:23:50 AM5/23/11
to web2py-users
I have been thinking about this but issue is, how should groups be
identified? By their name? The consumer app does not have the same
auth_group table. What if it has a group with the same name as a group
in the provider app?

Anyway... as it ism CAS (and cas in Auth) has a problem. Any consumer
can authenticate with it and therefore it will reveal information
about the user (for example the username and email). There are two
ways to restrict this: 1) have the provider filter consumers by IP/
domain; 2) have the user decide whether to authenticate with the
consumer (as in OpenID). I think 1 is more appropriate for CAS and
easier to implement.

Michele Comitini

unread,
May 23, 2011, 10:45:29 AM5/23/11
to web...@googlegroups.com
Could CAS server answer to questions such as "is operation bar allowed
to user foo"?

The list of operations is CAS server dependent, the consumer can ask
only for those...

mic

2011/5/23 Massimo Di Pierro <massimo....@gmail.com>:

Massimo Di Pierro

unread,
May 23, 2011, 11:15:18 AM5/23/11
to web2py-users
We should make a list of operations we want to support.

Anyway, I have one more revision.

Say you has two apps running on domains http://domain1/app1 and
http://domain2/app2 (where domain1 and domain2 can be 127.0.0.1:8000)
Now you simply do:

# In app1/models/db.py

auth = Auth(db=db)
auth.cas_domains.append('http://domain2') # allow app2 from domain2
auth.define_tables(username=True)

# In app2/models/db.py

auth = Auth(db=db,cas_provider='http://domain1/app1/default/user')
auth.define_tables(username=True)

At voila' app2 will use app1 for authentication.
username=True is optional.

Massimo

On May 23, 9:45 am, Michele Comitini <michele.comit...@gmail.com>
wrote:
> Could CAS server answer to questions such as "is operation bar allowed
> to user foo"?
>
> The list of operations is CAS server dependent, the consumer can ask
> only for those...
>
> mic
>
> 2011/5/23 Massimo Di Pierro <massimo.dipie...@gmail.com>:

Massimo Di Pierro

unread,
May 23, 2011, 11:21:20 AM5/23/11
to web2py-users
we could expose a has_memmbership and has_permission service to
authorized cas_consumers. The problem is that the consumers would have
to call special functions to check the provider. We could always
delegate the local has_membership and has_permission to the service
equivalent functions with there would be problems with referential
integrity because objects are local and permissions are remote.

Has anybody does this (even if not in wbe2py). Is there any
documentation?

massimo

On May 23, 9:45 am, Michele Comitini <michele.comit...@gmail.com>
wrote:
> Could CAS server answer to questions such as "is operation bar allowed
> to user foo"?
>
> The list of operations is CAS server dependent, the consumer can ask
> only for those...
>
> mic
>
> 2011/5/23 Massimo Di Pierro <massimo.dipie...@gmail.com>:

Massimo Di Pierro

unread,
May 23, 2011, 11:34:30 AM5/23/11
to web2py-users
we could support CAS 2 by default (with minimal changes) and do
something like this:

<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>q234wd325253</cas:user>
<cas:attribute name="username" value="jdoe"/>
<cas:attribute name="first_name" value="John"/>
<cas:attribute name="last_name" value="Doe"/>
<cas:attribute name="email" value="jd...@middlebury.edu"/>
...
<cas:attribute name="MemberOf" value="group-name"/>
<cas:attribute name="MemberOf" value="other-group-name"/>
...
</cas:authenticationSuccess>
</cas:serviceResponse>


On May 23, 10:21 am, Massimo Di Pierro <massimo.dipie...@gmail.com>
wrote:

Ross Peoples

unread,
May 23, 2011, 12:52:39 PM5/23/11
to web...@googlegroups.com
That would be nice. It has all the information required, plus group membership. Would this work with custom auth_user tables as well?

Massimo Di Pierro

unread,
May 23, 2011, 1:02:50 PM5/23/11
to web2py-users
It already does but only transfers user_id+username+email.

Ross Peoples

unread,
May 23, 2011, 1:10:36 PM5/23/11
to web...@googlegroups.com
Should it transfer all fields in auth_user, or should the application provide its own service to get more information if it needs to?

Massimo Di Pierro

unread,
May 23, 2011, 1:20:51 PM5/23/11
to web2py-users
I this it should transfer all fields that exist in both and are marked
as writable. The id will not be the same of course.

mart

unread,
May 23, 2011, 9:59:08 PM5/23/11
to web2py-users
This is great! I think you just rid of an issue I have been avoiding
to have to deal with! Merci!!!!!


question though: What do you by permissions are remote? remote to the
user or remote to the resources the user is trying to reach? my
thought was that everything is local to the resources
(object,permissions,authorizer)... example:

I am looking into the use of dummy authorizers for ftp access to a
build repository, where I am hoping to use the user's web2py
credentials for ftp access by doing something like:

auth = DummyAuthorizer()
authorizer.add_user('myBuildUser', 'myPassword', os.getcwd(),
perm='elradfmw')
authorizer.add_anonymous(os.getcwd(),perm="elr")

auth.add_user("jerry", "password", "/home/jerry", perm="elr") # read
only
auth.add_user("tom", "password", "/home/tom", perm="elradfmw") #
full r/w access

but this may not be efficient for groups, unless we can retrieve group
info in the users (i'm not smart enough yet to know the answer
here :)

so for groups, I was thinking also maybe:
since web2py and ftp service are on Linux (in my case), and since with
Unix authorizer doesn't store that kind of information at the OS level
(at lest i don't think it does), another solution
would be possibly to add a "global_perm" keyword argument to the ftp
service constructor which would apply to all users (except anonymous).
Example:

UnixAuthorizer(global_perm="elradfmw") # everyone gets r/w at the FTP
level, but we restrict at the OS level.

another option (which I don't how to do yet) would be to add an
function to deal with complicated groups (group a has r/w, groups B
has r only, groups c can r/w in THIS location but not in THAT
location, and our user 'jerry' is part of each group). I was thinking
that one solution would be to have an 'except' function like this:

auth = UnixAuthorizer(global_perm="elradfmw") # r/w for all
auth.except_user("jerry", perm="elr") # except jerry, he gets read

Again, I don't how to do this yet, but will eventually figure out
something (or give up and just give everyone r/w ;) )

Mart :)

On May 23, 11:34 am, Massimo Di Pierro <massimo.dipie...@gmail.com>
wrote:
> we could support CAS 2 by default (with minimal changes) and do
> something like this:
>
> <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
>     <cas:authenticationSuccess>
>         <cas:user>q234wd325253</cas:user>
>         <cas:attribute name="username" value="jdoe"/>
>         <cas:attribute name="first_name" value="John"/>
>         <cas:attribute name="last_name" value="Doe"/>
>         <cas:attribute name="email" value="j...@middlebury.edu"/>

Massimo Di Pierro

unread,
May 23, 2011, 10:43:47 PM5/23/11
to web2py-users
I moved from Cas 1 provider to Cas 2 provider. Changed the notation a
bit:

Say you has two apps running on domains http://domain1/app1 and
http://domain2/app2 (where domain1 and domain2 can be 127.0.0.1:8000)

# In app1/models/db.py
auth = Auth(db=db)
auth.cas_domains.append('http://domain2') # allow app2 from domain2
auth.define_tables(username=True)

# In app2/models/db.py
auth = Auth(db=db,cas_provider='http://domain1/app1/default/user/
cas')
auth.define_tables(username=True)

username=True is optional.

On May 23, 10:15 am, Massimo Di Pierro <massimo.dipie...@gmail.com>
wrote:
> We should make a list of operations we want to support.
>
> Anyway, I have one more revision.
>
> Say you has two apps running on domainshttp://domain1/app1andhttp://domain2/app2(where domain1 and domain2 can be 127.0.0.1:8000)

Massimo Di Pierro

unread,
May 23, 2011, 11:48:39 PM5/23/11
to web2py-users
Still working on this... not sure what the right way but...

if app2 delegates authentication to app1 and user changes profile on
app1, at next login his record on app2 is overwritten (the id and
registration_id stay the same but the other fields in common between
apps are updated)

On May 23, 9:43 pm, Massimo Di Pierro <massimo.dipie...@gmail.com>
wrote:
> I moved from Cas 1 provider to Cas 2 provider. Changed the notation a
> bit:
>
> Say you has two apps running on domainshttp://domain1/app1andhttp://domain2/app2(where domain1 and domain2 can be 127.0.0.1:8000)
>
> # In app1/models/db.py
> auth = Auth(db=db)
> auth.cas_domains.append('http://domain2') # allow app2 from domain2
> auth.define_tables(username=True)
>
> # In app2/models/db.py
> auth = Auth(db=db,cas_provider='http://domain1/app1/default/user/
> cas')
> auth.define_tables(username=True)
>
> username=True is optional.
>
> On May 23, 10:15 am, Massimo Di Pierro <massimo.dipie...@gmail.com>
> wrote:
>
>
>
>
>
>
>
> > We should make a list of operations we want to support.
>
> > Anyway, I have one more revision.
>
> > Say you has two apps running on domainshttp://domain1/app1andhttp://domain2/app2(wheredomain1 and domain2 can be 127.0.0.1:8000)
Reply all
Reply to author
Forward
0 new messages