openedx 是流行的开源mooc(慕课)平台,我这安装的是edx-ginkgo.2-7版本,cas是5.3.2
这个接入颇费了一番周折,总是设置不成功,因为没有可以直接参考的案例,只有edx的官方站点有些说明,但都是针对google,facebook,github等账号的第三方oauth2.0登录方法,增加自己的进入暂时没摸清门路,久攻不下,就换个思路,以facebook的葫芦,装cas的药,就是保持facebook第三方登录的名称,流程,把交互如登录,获取code,获取accesstoken,获取用户信息的网址换成自己的,把关键的处理字段换成自己的,几经周折,居然通过调试通过,终于把edx平台集成到cas统一登录认证。
记录如下,供自己和需要的同仁参考:
1.修改 lms.env.json 文件:
"FEATURES":"ENABLE_COMBINED_LOGIN_REGISTRATION": true,
"FEATURES":"ENABLE_THIRD_PARTY_AUTH": true,
这两个默认为false,改为true,开启第三方登录
2. 修改 lms.env.json 文件:
增加:
"THIRD_PARTH_AUTH_BACKENDS": [
"social.backends.facebook,FacebookOAuth2"
],
其中,起作用的是FacebookOAuth2,我自己的LinbsoftOAuth2并未起作用
3.修改lms.auth.json文件
"SOCIAL_AUTH_OAUTH_SECRETS": {
"facebook": "fdgerfgqwefwer233424244deefdweef",
"linbsoft": "fvrf434534534frfv2234324"
},
把该网站登录cas的clientSecret 写入这里
4.修改facebook.py
最好先备份该文件,会被改得面目全非,以下是完整源码
class FacebookOAuth2(BaseOAuth2):
"""Linbsoft cas OAuth authentication backend"""
name = 'facebook'
AUTHORIZATION_URL = 'https://author.linbsoft.com/cas/oauth2.0/authorize'
ACCESS_TOKEN_URL = 'https://author.linbsoft.com/cas/oauth2.0/accessToken'
ACCESS_TOKEN_METHOD = 'POST'
REDIRECT_STATE = False
def get_user_details(self, response):
"""Return user details from cas Linbsoft cas account"""
return {'username': response['id'],
'email': response['attributes']['mail'],
'fullname': response['attributes']['displayName'],
'first_name': response['id'],
'last_name': response['attributes']['sn']}
def user_data(self, access_token, *args, **kwargs):
"""Loads user data from service"""
return self.get_json('https://author.linbsoft.com/cas/oauth2.0/profile',
params={'access_token': access_token})
@handle_http_errors
def auth_complete(self, *args, **kwargs):
"""Completes loging process, must return user instance"""
self.process_error(self.data)
if not self.data.get('code'):
raise AuthMissingParameter(self, 'code')
state = self.validate_state()
key, secret = self.get_key_and_secret()
response = self.request(self.access_token_url(), params={
'client_id': key,
'redirect_uri': self.get_redirect_uri(state),
'client_secret': secret,
'grant_type': 'authorization_code',
'code': self.data['code']
})
str=response.content
s = str.find('access_token=')
e = str.find('&')
access_token = str[s+13:e]
return self.do_auth(access_token,response, *args, **kwargs)
def do_auth(self, access_token, response=None, *args, **kwargs):
response = response or {}
data = self.user_data(access_token)
if not isinstance(data, dict):
raise AuthUnknownError(self, 'An error ocurred while retrieving '
'users linbsoft data')
data['access_token'] = access_token
if 'expires_in' in response:
data['expires'] = response['expires_in']
kwargs.update({'backend': self, 'response': data})
return self.strategy.authenticate(*args, **kwargs)
这段源码除了保留facebook的名字接口,处理逻辑做了大的修改,并精简了不需要的如获取头像,朋友列表等代码
5. 管理员在edx主机上以 http://localhost/admin 方法进入管理界面
6. 登录后找到Third_Party_Auth节 的Provider Configuration(OAuth) 点增加
在增加的对话栏中,设置或输入
enable: 打勾 允许第三方登录的这个设置项,
visible: 打勾,在登录界面会显示第三方登录按钮
Backend name: 选facebook (关键在这里,自己增加的backend不出现在这里,没法选,只能套用facebook的,这个慢慢再摸索)。
provider slug: 输入facebook
client ID: 输入自己在cas服务器设置的id
client sercet: 输入自己在cas服务器设置的secret密钥
修改好后点保存,可以看到自己增加的配置项
7. 退出admin,重新启动apache和edx
8. 在浏览器输入自己的openedx网站地址,检验成果
在登录页,多了一个第三方登录按钮,点击后,即能实现第三方登录
如果第一次从cas单点登录过来,根据设置策略,会要求你用账号密码再登录一次,就自动完成了cas账号和edx账号的对应绑定关系,也可以创建一个新的edx账号,并自动绑定。
在创建新账号时,从cas获取的用户名,邮箱,姓名等会自动填充到注册页面。
我选择的是自动创建edx账号,自动激活,cas账号登录过来,自动完成创建,激活,登录edx账号的全过程
9. 大团圆结局,cas通过oauth2.0登录edx成功
edx用户可以查看自己的关联状态