OAuth2单点登陆无法生效

请按照以下模版详细描述您遇到的问题:

当前服务器版本

Ubuntu 24.04.3 LTS

seafile CE 13

部署/操作过程

已有反向代理、域名、证书

docker部署sefile13

按手册部署完成,测试可以正常上传下载,额外配置的CollaboraOnline也可以正常编辑。

期望使用泛微OA的OAuth2认证服务单点登陆

按英文手册增加了OAuth2相关配置

ENABLE_OAUTH = True

# 如果在用户首次登录 Seafile 时创建新用户,默认值为 `True`.

OAUTH_CREATE_UNKNOWN_USER = True

# 如果新用户首次登录 Seafile 时是激活状态,默认值为 `True`.

OAUTH_ACTIVATE_USER_AFTER_CREATION = True

# 通常 OAuth 通过 SSL 层工作。如果您的服务器未配置为允许 HTTPS,某些方法将引发“oauthlib.oauth2.rfc6749.errors.InsecureTransportError”。将此设置为 `True` 可避免此错误.

OAUTH_ENABLE_INSECURE_TRANSPORT = True

# 当您注册客户端应用程序时,授权服务器生成的客户端ID/密钥.

OAUTH_CLIENT_ID = “aaaaaaaa-bbbb-cccc-dddddddd”

OAUTH_CLIENT_SECRET = “***********************”

# 当用户身份验证成功时的回调 URL。请注意,您在注册客户端应用程序时输入的重定向 URL 必须与此值完全相同.

OAUTH_REDIRECT_URL = ‘seafile地址/oauth/callback/’

# OAUTH_PROVIDER_DOMAIN将被弃用,可以替换为 OAUTH_PROVIDER,此变量在数据库中用于标识第三方提供商,可以是域,也可以是少于 32 个字符的易于记忆的字符串.

OAUTH_PROVIDER_DOMAIN = ‘泛微OA’

OAUTH_PROVIDER = ‘泛微OA’

OAUTH_AUTHORIZATION_URL = ‘泛微oa地址/sso/oauth2.0/authorize’

OAUTH_TOKEN_URL = ‘泛微oa地址/sso/oauth2.0/accessToken’

OAUTH_USER_INFO_URL = ‘泛微oa地址/sso/oauth2.0/profile’

OAUTH_SCOPE = [“user”,]

OAUTH_ATTRIBUTE_MAP = {

“attributes.workcode”: (False, “name”),

“attributes.email”: (False, “contact_email”),

“id”: (True, “uid”),

# Seafile v11.0 +

}

泛微的用户信息接口返回的具体用户信息在attributes集合里,先照着写成这样

错误截图

登陆界面有“单点登陆”,点击后会正常跳转到泛微登陆界面,泛微账号登陆后回到seafile界面显示“出错了,请联系管理员”

错误日志

seahub.log中显示seahub.oauth.views:168 oauth_callback (missing_code) Missing code parameter in response.

检查泛微的说明发现,泛微authorize接口返回的参数名是ticket,而后续getToken接口需要code参数,内容就是ticket的内容

这个怎么转换?

浏览器控制台错误信息(如果相关,请提供截图信息)

应该是oauth回调携带的参数不是标准的code参数, 而是ticket, 可以到容器里修改一下代码,看看返回的参数是什么?可以按着这里修改自己调试一下

感谢提供文件修改位置,最终成功使用泛微OAuth2单点登陆


发现OAuth2设置手册漏东西,废老半天才运行成功

首先是泛微接口返回的参数名称不是code而是ticket的问题,还挺好解决,seafile使用第三方库实现OAuth2功能,提供fetch_token()来获取token并对接口返回的内容检查是否存在access_token值,这个函数可以自动从回调URL中解析code值,也可以单独设置code值。seafile默认是从URL中解析,所以手工加上code值设置即可。

# 修改/opt/seafile/seafile-server-13.0.12/seahub/seahub/oauth/views.py 第146行开始
        token = session.fetch_token(
            TOKEN_URL,
            client_secret=CLIENT_SECRET,
            include_client_id=INCLUDE_CLIENT_ID,
            code=request.GET.get('code',request.GET.get('ticket')), # 添加这一行
            authorization_response=service_url + request.get_full_path())

这样设置后还是无法使用,日志报错oauth_callback (missing_token) Missing access token parameter. 排查后发现这个是第三方库的回报,意思是接口返回的内容里没有找到名为access_token的值,泛微getToken接口返回报错了。

仔细查看fetch_token()的说明,发现include_client_id参数控制请求时是否带client_id,这个是读取设置项OAUTH_INCLUDE_CLIENT_ID,手册没有写这个设置项

在seahub_settings.py内加上设置项OAUTH_INCLUDE_CLIENT_ID = True

完成修改后结果还是不行,日志报错

oauth_callback Required user attr not found.
oauth_callback {‘msg’: ‘missing accessToken’, ‘code’: ‘1011’, ‘status’: 400}

报错内容里是获取用户信息接口的报错,缺少token,但经测试fetch_token()已经成功获取到token了。

再检查后发现,在获取用户信息的部分会读取一个设置项OAUTH_ACCESS_TOKEN_IN_URI,判断是否在请求获取用户信息时带上token,而这个设置默认是False。手册也没有写这有这个设置项。

在seahub_settings.py内加上设置项OAUTH_ACCESS_TOKEN_IN_URI = True

重启seafile,成功单点登陆