您的位置:首页 > 编程语言 > Python开发

CAS单点登录python客户端分析

2016-01-19 21:09 881 查看
项目中用到CAS,做完也是有些时间了,当时也是在网上找了好多资料,研究了好久才慢慢弄明白(其实现在也不是很明白,但是能够满足项目的需要了。。。),自己有些感悟,现在回想下通过博客记录下来,供有需要的翻看。

CAS单点登录具体就不介绍,再此介绍下请求到CAS的过程

一.通过url配置让某些访问请求转到cas验证(settings文件及其他地方配置安装,,,略):

url(r'^login/$', cas.views.login'cas.views.login',name='login'),

二。cas.views.login 方法有两方面的作用

         1.若请求中没有携带ticket,则转到 CASlogin URL

         2.若请求中带了ticket,则验证CASticket的有效性

对于第1种情况,请求中没有携带ticket:

会拼凑出向CAS发送登录请求的url:





CAS端处理完请求后会返回ticket,然后在根据请求中的service返回到之前请求的url,然后到第2点

 

这里,我着重在第2点讲述:

若请求中携带了ticket,则会验证ticket的有效性,并对user进行鉴权

如源码:

在cas.views.login方法中:

if ticket:
user = auth.authenticate(ticket=ticket, service=service)
这个auth.authenticate方法会调用在settings中配置的backend

AUTHENTICATION_BACKENDS = (
'cas.backends.CASBackend',
)
如源码:
def authenticate(**credentials):
"""
If the given credentials are valid, return a User object.
"""
for backend, backend_path in _get_backends(return_tuples=True):
try:
inspect.getcallargs(backend.authenticate, **credentials)
except TypeError:
# This backend doesn't accept these credentials as arguments. Try the next one.
continue

try:
user = backend.authenticate(**credentials)
…略…


下来的工作便交给到CASBackend.authenticate的方法对ticke进行验证

这个方法最终会调用_internal_verify_cas(ticket, service, suffix)这个方法

_internal_verify_cas方法是基于xml验证CAS 2.0 和 CAS 3.0版本 ticket的,验证成功会返回一个username,验证失败则返回failure

验证方式:         

_internal_verify_cas方法通过拼凑url方式拼凑一个url向CAS服务器发送一个请求,该请求会返回一个带有xml格式数据的验证信息的jsp页面(若验证成功,xml里会包含username节点的数据)

拼凑的url:
url = (urljoin(settings.CAS_SERVER_URL, suffix) + '?' + urlencode(params))




该部分源码:

def _internal_verify_cas(ticket, service, suffix):
"""Verifies CAS 2.0 and 3.0 XML-based authentication ticket.

Returns username on success and None on failure.
"""

params = {'ticket': ticket, 'service': service}
if settings.CAS_PROXY_CALLBACK:
params['pgtUrl'] = settings.CAS_PROXY_CALLBACK

url = (urljoin(settings.CAS_SERVER_URL, suffix) + '?' +
urlencode(params))

page = urlopen(url)

username = None

try:
response = page.read()
tree = ElementTree.fromstring(response)
document = minidom.parseString(response)

if tree[0].tag.endswith('authenticationSuccess'):
if settings.CAS_RESPONSE_CALLBACKS:
cas_response_callbacks(tree)

username = tree[0][0].text
…略…
else:
failure = document.getElementsByTagName('cas:authenticationFailure')
if failure:
logger.warn('Authentication failed from CAS server: %s',
failure[0].firstChild.nodeValue)


至此,若验证成功,则可以将username返回

Username返回到CASBackend.authenticate方法:
username = _verify(ticket, service)

获得这个username会做判断:

1.   若已存在这个username的user,则查询出来返回这个user

2.   若不存在这个username的user,则创建这个user并返回

到此时,便验证成功了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cas登录分析