简介
这是上一篇”创建AWS ECS Fargate“中申引部分“SSO OpenID”的展开,上篇中我们通过ECS Fargate运行了一个web的应用,任何人都可以直接访问。
现实场景中我们一般只允许授权用户访问应用,可以给这个web应用写一个单独授权页面逻辑,然后配合后台数据库存储用户信息来实现。
这种方法对单个应用有效,但是对于有十几甚至几十上百个应用的企业用户来说,给每个应用写一次逻辑页面的做法显然不合理。
这就轮到SSO(Single Sign On)出场了。当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联应用的权限,而开发人员也不必为每个应用加授权页面。
一般企业往往已经建好自己的身
份识别服务identity provider(IdP)或利用身份识别服务商提供的服务,我们在开发新应用时经常面对的情况是,如何把新系统加入到现有的SSO服务中。
OpenID体系主要由 OpenID Connect Relying Party(RP)和 OpenID Connect Provider(OP)两部组成。OP提供用户验授权的服务,RP则是把用户请求转发至OP,流程如下。
更直观的流程
上图中OpenID Provider(OP)就是企业建好的身份识别服务,而我们一般要实现的是红圈中的RP的功能。
本文在httpd官方docker镜像的基础上加入mod_auth_openidc生成支持RP功能的镜像,在Fargate中用新镜像生成容器,利用已有的身份识别服务(OP)进行SSO登录测试。
目录
- 环境(配置)
- 实战步骤
- 从客户处获得OP相关信息
- 编写镜像需要的控制文件
- oidc.conf
- Dockerfile
- httpd.conf
- 生成镜像并推进仓库
- 更新service
- 检查结果
- 引申
- 资源下载
- 后记
环境(配置)
- AWS中国或Global帐号,可在官网申请,一年内使用指定资源免费
- AWS cli, 本文在win10 + terminal下使用aws cli
- linux + docker 或 win + docker
实战步骤
1. 从客户处获得OP相关信息
首先客户需在OP注册新网站域名,获得OP相关接口openid-configuration,Client ID/Secret,及客户已使用的OpenID命名规则等信息。
OP 接口例子
如果客户提供openid-configuration链接,则这个链接里包括了所有必要的接口,只配置此链接就可以,下文即采用这种方式。
2. 编写镜像需要的控制文件
在linux或者windows上建如下结构的目录和文件。
提示:下列文件及所需要的软件包可以本文“资源下载”中下载
└── Fargate_SSO
├── conf
│ ├── htaccess
│ ├── httpd.conf
│ └── oidc.conf
├── Dockerfile
├── entrypoint.sh
├── libapache2-mod-auth-openidc_2.3.11-1.stretch+1_amd64.deb
└── test.html
oidc.conf
oidc.conf是openid插件的控制文件。OP信息,受保护网站地址,指定header如何获取登录用户信息等,均写在此文件中。下面只列出了需要重点关注的配置信息,完整的控制文件见“资源下载”。
提示:你也可以把这些内容直接写到httpd.conf中,但出于易维护原则我们一般单独写此文件
# Path which should be protected by this module. Default is "/" (everything.)
<Location />
AuthType openid-connect
Require valid-user
</Location>
<Location /test.html>
Satisfy Any
Allow from all
</Location>
#Ping OpenID Connect Configuration URL
OIDCProviderMetadataURL https://yourOPsite.com/fss/.well-known/openid-configuration
# Client ID. Your OP provides
OIDCClientID example_client_id
# Client secret. Must keep secret. Your OP provides
OIDCClientSecret XXXXXX
# Redirect URI. Empty location where mod_auth_openidc can accept tokens from Ping.
# IMPORTANT: must be inside of "protected resource" path above.
OIDCRedirectURI https://theSiteYouWantToProvide.com/redirect_uri
# variable where SSO is passed
OIDCAuthNHeader XX_USER
说明:
- 第一部分Location 指定域名根目录下都需要进行sso保护
- 第二部分Location 指定根目录下的test.html页面不需要保护,在访问时不会弹出SSO界面。一般这种页面可以做为aws target group中的健康检查页面,另外一些不需要SSO保护的css表单等资源也会加在这里,支持文件夹
- OIDCProviderMetadataURL 客户给的openid-configuration地址,RP会从这个地址中获得所需的各种OP接口信息
- OIDCClientID 客户提供的要保护网站的client id
- OIDCClientSecret 客户提供的要保护网站的client secret
- OIDCRedirectURI 保护网站的地址,“/redirect_uri”是固定项,和不同的OP设置有关,具体需要向客户确认
- OIDCAuthNHeader 指定从request请求中获得登录用户SSO信息的header名称,也需和客户确认。
Dockerfile
Dockerfile用来描述要生成的image中的内容,安装的软件包,打开的端口,运行方式等。
FROM httpd:2.4
COPY ./test.html/ /usr/local/apache2/htdocs/dist/test.html
COPY conf/htaccess /usr/local/apache2/htdocs/.htaccess
COPY entrypoint.sh /entrypoint.sh
COPY conf/oidc.conf /usr/local/apache2/conf/
COPY conf/httpd.conf /usr/local/apache2/conf/
COPY libapache2-mod-auth-openidc_2.3.11-1.stretch+1_amd64.deb /user/local/libapache2-mod-auth-openidc_2.3.11-1.stretch+1_amd64.deb
RUN apt-get update\
&& DEBIAN_FRONTEND=noninteractive apt-get install -y apt-utils openssh-server --allow-unauthenticated libapache2-mod-auth-openidc=2.1.6-1 \
&& dpkg -i /user/local/libapache2-mod-auth-openidc_2.3.11-1.stretch+1_amd64.deb \
&& rm -rf /user/local/libapache2-mod-auth-openidc_2.3.11-1.stretch+1_amd64.deb
EXPOSE 80 443
ENTRYPOINT ["/entrypoint.sh"]
可以看到,在dockerfile中指定了从当前conf目录中复制oidc.conf和httpd.conf到镜像中。
提示:我们通过apt-get自动安装老版本oidc插件,这样可以把相关联的包都自动装好,然后就可以顺利安装新版本的插件
3. 生成镜像并推进仓库
用docker命令行工具生产镜像,打tag并推入指定镜像仓库,运行环境需要连接internet或者通过http/https连接internet。
在Fargate_SSO目录中运行命令
docker build --tag awstestoidc .
运行结果,生成镜像35c1ba41a00b
打tag后推入镜像仓库
docker tag 35c1ba41a00b:latest tansong0091/httpd-oidc:test-only
docker push tansong0091/httpd-oidc:test-only
提示:在push之前需要用docker login的命令登入仓库。这里是把镜像推送到公共的docker hub中,生产中我们会推入企业私有仓库
镜像生成推入完成,下一步是在ECS Fargate中用新镜像生成task实例。
4. 更新service
修改“创建ECS Fargate”文章中tstest_task.json文件的containerDefinitions部分,把image改成新生成的镜像名称“tansong0091/httpd-oidc:test-only”。注意是全称,要包括repository(tansong0091)这部分。
{
...
"containerDefinitions": [
{
"name": "fargate-app1",
"image": "tansong0091/httpd-oidc:test-only",
...
}
然后运行新建task命令
aws ecs register-task-definition --cli-input-json file://tstest_task.json
提示:如果运行命令时报错[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed,可添加–no-verify-ssl如下
aws ecs register-task-definition --cli-input-json file://tstest_task.json --no-verify-ssl
从aws ecs register-task-definition返回的结果中取得task版本号,如“3”。修改“创建ECS Fargate”文章中update-svc.json文件,把taskDefinition中最后数字改成“3”。
{
"cluster": "tstest",
"service": "tstest-svc",
"desiredCount": 1,
"taskDefinition": "tstest-fargate-task:3",
...
"forceNewDeployment": true,
...
}
运行update service命令,更新镜像
aws ecs update-service --cli-input-json file://update-svc.json
5. 检查结果
在浏览器中输入建好的ALB的DNS可以看到SSO界面弹出,输入正确的用户密码后会跳入应用页面。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fnWxq4d2-1614168713771)(https://imgkr2.cn-bj.ufileos.com/8203ef13-e9d8-464f-bdb9-443600e0fc24.jpg?UCloudPublicKey=TOKEN_8d8b72be-579a-4e83-bfd0-5f6ce1546f13&Signature=%252FSoJJQfMCggGY3qNvdX9mdE%252FgEI%253D&Expires=1614147785)]
当在览器中输入http://DNS/ts/test.html时,并不会出现SSO界面,而是直接显示测试页面,因为我们在oidc.conf中把/ts/test.html取消了SSO保护
引申
-
迁移兼容
本文中在ECS Fargate中启用了openid的httpd容器,实现了RP功能,把通过此容器的request请求加上了SSO保护。因为用的是docker镜像,所以这个容器可以无缝迁移到其它容器环境,比始说k8s, Azure等。进一步来说我们还可以把这个结构运行在传统的本地VM或者物理机上。事实上我们的生产环境中已经采用了VM+docker的结构,极大减化了传统部署升级的复杂性,同时节省了后续向云上迁移的改造成本。 -
注意事项
oidc.conf中OIDCRedirectURI里的网址需要加http或者是https按网站实际情而定。
本文需要额外的OP才能进行测试,搭建OP不在本测试范围内。
资源下载
OpendID详细说明
https://openid.net/
模板文件下载,注意需要修改
https://github.com/tansong0091/realCrapForAWS/tree/main/Fargate_SSO
mod_auth_openidc插件详细说明
https://github.com/zmartzone/mod_auth_openidc/blob/master/auth_openidc.conf
后记
SSO登录是企业的标配,新上的应用肯定要进行SSO集成。SSO配置涉及到的方面比较多,知识比较杂,再加上OP的设置各不相同,要上手有一定难度。本文仅做抛砖引玉,能给需要的人一点方向就够了。
喜欢请关注公众号“全是AWS干货”
本文由博客群发一文多发等运营工具平台 OpenWrite 发布