天坑:如何将Discourse与SimpleSAMLphp连接,作为SAML身份验证提供者(IDP)使用

Discourse其实内置了一个DiscourseSSO(现在叫DiscourseConnect),也就是官网那篇“Using Discourse as an identity provider (SSO, DiscourseConnect)”,但是你只要多看几眼就会发现,它提供的并不是标准SAML或者Oauth协议,而是一套它自己写好的API之类的东西。

那么怎么办呢?没关系,有一个巨佬已经帮我们写好了Discourse-SimpleSAMLphp这个插件了,这个插件允许我们将DiscourseConnect(DiscourseSSO)连接到SimpleSAMLphp然后使用SimpleSAMLphp来提供标准SAML服务。

那么接下来我们只需要花那么一丢丢时间弄懂什么是SimpleSAMLphp以及怎么配置它就好啦(笑死,根本弄不懂

首先是从官网下载它的本体。

1
wget https://simplesamlphp.org/download?latest

然后解压

1
tar zxf download?latest

然后把解压出来的东西挪到/var/simplesamlphp这个目录

1
sudo cp -a simplesamlphp-1.x.y/. /var/simplesamlphp/

然后将该文件夹授予www-data用户和755权限

1
2
sudo chown -R www-data:www-data /var/simplesamlphp/
sudo chmod -R 755 /var/simplesamlphp/

它们默认是从GitHub抓的,所以要是你没开代理,那麻烦你下载它们的包之后上传到 /var/simplesamlphp 去。

你可能会问为什么一定得是在/var/simplesamlphp,很简单,因为官方教程就是放在这的,放别的地方要额外配置。

然后是将首页指向它文件夹里的www,然后配置nginx。如果你是apache,那它官网有对应的配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
upstream saml-php-handler {
server unix:/run/php/php8.0-fpm.sock;
}
server {
listen 443 ssl;
server_name 这里填你的域名;
index index.php;
ssl_certificate 这里填你的证书;
ssl_certificate_key 这里填你的私钥;

ssl_protocols TLSv1.3 TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;

location ^~ /simplesaml {
alias /var/simplesamlphp/www;

location ~ ^(?<prefix>/simplesaml)(?<phpfile>.+?\.php)(?<pathinfo>/.*)?$ {
include fastcgi_params;
fastcgi_pass saml-php-handler;
fastcgi_param SCRIPT_FILENAME $document_root$phpfile;
# Must be prepended with the baseurlpath
fastcgi_param SCRIPT_NAME /simplesaml$phpfile;
fastcgi_param PATH_INFO $pathinfo if_not_empty;
}
}
}

解释一下upstream saml-php-handler:saml-php-handler是为了防止你有别的已经占用了php-handler,就这么简单。在示例里我用的是php8.0,你在用什么版本的php就改成什么版本的。

然后更新一下源:

1
sudo apt update

然后安装软件包:

1
sudo apt install php-xml php-mbstring php-curl php-memcache php-ldap memcached

注意,这里需要根据你php对应的版本来安装,比如你是php8.0,就需要在所有”php”的后面添8.0,如:php8.0-xml

安装完成后,重新启动 Nginx 以激活新的 PHP 扩展:

1
sudo systemctl restart Nginx

然后生成一个盐:

1
openssl rand -base64 32

复制下来这串盐。

然后打开/var/simplesamlphp/config/config.php

找到’auth.adminpassword’,改成你自己的密码;

找到’secretsalt’,改成你刚刚生成的那串盐;

找到’technicalcontact_name’,改成你的名字;

找到’technicalcontact_email’ ,改成你的邮箱;

找到 ‘language.default’,改成’zh’(也可以改成你的语言);

找到’timezone’,将 null 改成 ‘Asia/Shanghai’ (如果你在中国),或者改成你所在的地区;

最后,找到’enable.saml20-idp’,将其改为’true’,启动SAML IDP功能。

然后打开 https://你的域名/simplesaml ,理论上它就能访问了。

然后安装composer。

1
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
1
php composer-setup.php
1
sudo mv composer.phar /usr/bin/composer

然后理论上你就能直接敲 composer 来运行了。

然后去/var/simplesamlphp ,编辑composer.json ,将version改成dev-master。这里这么做的原因是将discourse连接到simplesamlphp的那个插件在设置里写定了要求版本是dev-master,但实际上默认那里面写的是版本号,所以需要将版本号改为dev-master。

然后开始安装这个插件。

1
composer require swcc/simplesamlphp-module-authdiscourse dev-master --ignore-platform-reqs

–ignore-platform-reqs 这个参数是为了防止你使用的php版本是8.0而出现错误。
不出意外的话你应该能看见composer在/var/simplesamlphp欢快地跑着,开始安装swcc/simplesamlphp-module-authdiscourse了。

安装完成后,在/var/simplesamlphp输入

1
touch modules/authdiscourse/enable

让这个插件启动。




然后在你的discourse论坛启动 enable discourse connect provider 和 discourse connect provider secrets 这两个选项。

在 discourse connect provider secrets 输入你的SAML域名,比如login.example.com和你设定的一个SSO密钥。

然后编辑simplesamlphp文件夹里的config/authsources.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

$config = [
// This is a authentication source which handles admin authentication.
'admin' => [
'core:AdminPassword',
],

// This is the authentication source using the Discourse authentication.
'discourse-sso' => [
'authdiscourse:Discourse',
'url' => 'https://discourse.your-domain.org',
'secret' => '<your-sso-secret>',
],
];

主要是往合适的地方加上

1
2
3
4
5
'discourse-sso' => [
'authdiscourse:Discourse',
'url' => '你的论坛域名',
'secret' => '你刚刚设置的SSO密钥',
],

这一段,让它的认证方式添加上discourse。

最后,打开 https://你的SAML域名/simplesaml/module.php/core/authenticate.php?as=discourse-sso

或者

打开 https://你的SAML域名/simplesaml/ 然后点 认证/authentication 然后点discourse-sso然后测试。

如果返回了正确的信息,则说明你配置成功。

然后你需要配置你的IDP。

首先生成一个证书:

1
openssl req -newkey rsa:3072 -new -x509 -days 3652 -nodes -out 你的域名.crt -keyout 你的域名.pem

然后如果你是在root根目录生成的,你就能在root根目录看见你生成的新证书。

然后把证书挪到你需要放的地方,将它们赋予到用户www-data和755权限

1
2
chown -R www-data:www-data /你的证书存放路径
chmod -R 755 /你的证书存放路径

最后,在metadata/saml20-idp-hosted.php里,编辑你的证书路径和修改你的认证方式即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
$metadata['__DYNAMIC:1__'] = [
/*
* The hostname for this IdP. This makes it possible to run multiple
* IdPs from the same configuration. '__DEFAULT__' means that this one
* should be used by default.
*/
'host' => '__DEFAULT__',

/*
* The private key and certificate to use when signing responses.
* These are stored in the cert-directory.
*/
'privatekey' => '你的pem路径',
'certificate' => '你的crt路径',

/*
* The authentication source which should be used to authenticate the
* user. This must match one of the entries in config/authsources.php.
这里需要将认证方法改成discourse-sso
*/
'auth' => 'discourse-sso',
];

现在你的SimpleSAMLphp以可使用Discourse作为用户数据库后端,作为SAML IDP,提供标准SAML登录协议。

IDP实体标识符:https://你的域名/simplesaml/saml2/idp/metadata.php

URL目标(用于SP发送验证请求):https://你的域名/simplesaml/saml2/idp/SSOService.php

X509证书:https://你的域名/simplesaml/module.php/saml/idp/certs.php/idp.crt

或者对于支持直接上传IDP Metadata文件的服务商,干脆直接下载IDP Metadata:https://你的域名/simplesaml/saml2/idp/metadata.php

到此,大功告成。

enjoy~

下一篇我会详细介绍如何将由Discourse驱动的SimpleSAMLphp与NextCloud连接作为NextCloud的SAML登录方式。

有什么不懂的地方或有什么可以指正的地方欢迎随时联系admin@rail.moe