XWiki对接OpenID Connect认证系统

研究XWiki对接OIDC认证花了不少时间,主要还是由于网上资料较少尤其是中文资料,而且涉及到的扩展官方文档也不够详细,过程中主要有两个难点:

  • 非标准端口认证过程中的转跳不正确
  • 接入OIDC认证后与原有账户的关联问题

本文使用的OpenID Connect的服务是 Authelia

Nginx反向代理XWiki

由于OpenID Connect需要以TLS为基础,所以使用Nginx反向代理XWiki为其提供https服务,配置如下

server {
  listen 8443 ssl http2;
  listen [::]:8443 ssl http2;
  server_name  _;
  include ssl/nginx_ssl.conf;
  error_log /var/log/nginx/xwiki_error.log error;
  access_log /var/log/nginx/xwiki_access.log combined;

  location / {
    proxy_pass         http://127.0.0.1:8080;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   Host      $host;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection 'upgrade';
    proxy_cache_bypass $http_upgrade;
    proxy_set_header   X-Forwarded-Host $http_host;
    proxy_set_header   X-Forwarded-Server $http_host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
  }
}

由于XWiki通过Http的Header来生成自身的一些路径,经过反向代理后丢失必要的Header就导致转跳错误,尤其是使用非标准端口时。

注意X-Forwarded-Host使用$http_host而不是$host,否则会丢失端口信息,传入X-Forwarded-Proto告知服务的协议

安装OIDC扩展并进行配置

安装OpenID Connect Authenticator扩展,文档地址如下

https://extensions.xwiki.org/xwiki/bin/view/Extension/OpenID%20Connect/OpenID%20Connect%20Authenticator/

编辑xwiki.cfg文件修改以下三个变量

#-# Host and Protocol
xwiki.home=https://example.com:8443/
xwiki.url.protocol=https
#-# OIDC authentication management class
xwiki.authentication.authclass=org.xwiki.contrib.oidc.auth.OIDCAuthServiceImpl

xwiki.homexwiki.url.protocol也是为了XWiki能够获取到正确自身的路径,感觉XWiki代码也不同,有的是通过Header,有的地方通过配置文件来获取Host地址,所以最好两个地方都配置好。xwiki.authentication.authclass指定认证类为OpenID Connect Authenticator扩展的认证类名。

编辑xwiki.properties添加以下配置

oidc.skipped=false
oidc.clientid=xwiki
oidc.secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
oidc.endpoint.authorization=https://auth.example.com/api/oidc/authorization
oidc.endpoint.token=https://auth.example.com/api/oidc/token
oidc.endpoint.userinfo=https://auth.example.com/api/oidc/userinfo
# oidc.endpoint.logout=
oidc.scope=openid,profile,groups,email
oidc.user.nameFormater=${oidc.user.preferredUsername._clean}
oidc.user.subjectFormater=${oidc.user.preferredUsername._clean}

oidc.user.subjectFormater需要设置为OIDC服务返回preferred_username,默认为sub,是UUID格式,不便于区分。通过用户名来关联之前存在的用户,否则通过OIDC登陆后的用户会创建为username-0这样的用户。

为了实现关联之前存在的用户还需要编辑原有用户的Object。首先需要先编辑xwiki.cfg文件中的xwiki.superadminpassword来配置superadmin的密码,重启xwiki生效,然后使用superadmin登陆系统使用对象编辑器来编辑用户。 如下图将Subject设置为OIDC服务中身份对应的preferred_username,Issuer设置为OIDC服务的地址。

其他

XWiki目前只支持单一方式认证,使用了OIDC认证就不能使用内部的认证或者其他外部认证。 不过OpenID Connect Authenticator扩展有个骚操作可以跳过OIDC认证使用内部认证以便登陆超级用户等内部账号或者用来调试,在URl添加oidc.skipped=true参数即可。 如https://example.com:8443/bin/view/Main/?oidc.skipped=true