写点什么

5 分钟部署一个 OIDC 服务并对接 nightingale

用户头像
冯骐
关注
发布于: 2021 年 03 月 15 日

前言

就如在5 分钟部署一个 OAuth2 服务并对接 Shibboleth-IdP 3.4.6中提过的那样,OAuth2 作为一个授权协议,他对于认证的部分是缺乏标准规范的。这就是 OpenID Connect ——简称 OIDC 诞生的原因。


下图是 OpenID Connect 的架构,这里的 Core 部分主要基于 OAuth2.0 协议,增加了一个基于 JWT 的 id_token 机制,同时规定了 userinfo 的 endpoint。同时在 Discovery 中允许自动发现各个 endpoint 的 URL 地址,因此对于 OIDC 的 SSO 集成在全流程都是标准化的,同时他也向下兼容 OAuth2.0 ,因此有很好的客户端兼容性。



Apereo CAS - OIDC

是的,Apereo CAS 也可以支持 OIDC,所以如果你已经按照 15 分钟部署一个 CAS 服务并对接 Shibboleth-IdP 3.4.6 的路程部署好了 CAS 服务的话,那么只需要略微的调整,就可以让他支持 OIDC 了,5 分钟足矣。


下文假定已经安装好了 cas 6.1



  1. 修改 build.gradle ,在 dependencies 内进一步增加 oidc 的编译依赖


dependencies {    // Other CAS dependencies/modules may be listed here...     compile "org.apereo.cas:cas-server-support-json-service-registry:${casServerVersion}"     compile "org.apereo.cas:cas-server-support-ldap:${casServerVersion}"     compile "org.apereo.cas:cas-server-support-oidc:${project.'cas.version'}"}
复制代码

注意 cas 目前已经更新到 6.3 版本,6.2 以后的版本在 build.gradle 中的配置有所区别,如果你使用的是新版本的话,此处因使用类似这样的格式引入。

dependencies {    // Other CAS dependencies/modules may be listed here...     implementation "org.apereo.cas:cas-server-support-json-service-registry:${casServerVersion}"     implementation "org.apereo.cas:cas-server-support-ldap:${casServerVersion}"     implementation "org.apereo.cas:cas-server-support-oidc:${casServerVersion}"}
复制代码


  1. 在 cas-overlay-template/etc/cas/services/ 目录内新增 oidc-n9e-1004.json 文件,给夜莺注册 oidc 服务。注意这里 serviceId 要匹配夜莺 rdb.yml 中配置的 redirectURL



{  "@class" : "org.apereo.cas.services.OidcRegisteredService",  "clientId": "client",  "clientSecret": "secret",  "serviceId" : "^(https)://n9e.example.org.*",  "name": "OIDC",  "id": 1004}
复制代码
  1. 修改 cas-overlay-template/etc/cas/config/cas.properties,增加这条配置。

cas.authn.oidc.issuer=${cas.server.name}/cas/oidc/
复制代码

现在执行 ./docker-build.sh 重新生成 docker 镜像,并重新运行之。我们的 OIDC 服务就部署好了。访问 https://cas.example.org/cas/oidc/.well-known 试试看,应该可以看到 OIDC 的各项源数据信息了

{	"issuer": "https://cas.example.org/cas/oidc/",	"scopes_supported": ["openid", "profile", "email", "address", "phone", "offline_access"],	"response_types_supported": ["code", "token", "id_token token"],	"subject_types_supported": ["public", "pairwise"],	"claim_types_supported": ["normal"],	"claims_supported": ["sub", "name", "preferred_username", "family_name", "given_name", "middle_name", "given_name", "profile", "picture", "nickname", "website", "zoneinfo", "locale", "updated_at", "birthdate", "email", "email_verified", "phone_number", "phone_number_verified", "address", "gender"],	"grant_types_supported": ["authorization_code", "password", "client_credentials", "refresh_token"],	"id_token_signing_alg_values_supported": ["none", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512", "HS256", "HS384", "HS512"],	"id_token_encryption_alg_values_supported": ["RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW", "A128GCMKW", "A192GCMKW", "A256GCMKW", "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"],	"id_token_encryption_enc_values_supported": ["A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A192GCM", "A256GCM"],	"userinfo_signing_alg_values_supported": ["none", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512", "HS256", "HS384", "HS512"],	"userinfo_encryption_alg_values_supported": ["RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW", "A128GCMKW", "A192GCMKW", "A256GCMKW", "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"],	"userinfo_encryption_enc_values_supported": ["A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A192GCM", "A256GCM"],	"introspection_endpoint_auth_methods_supported": ["client_secret_basic"],	"token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post", "client_secret_jwt", "private_key_jwt"],	"code_challenge_methods_supported": ["plain", "S256"],	"claims_parameter_supported": true,	"request_parameter_supported": false,	"backchannel_logout_supported": true,	"frontchannel_logout_supported": true,	"jwks_uri": "https://cas.example.org/cas/oidc/jwks",	"token_endpoint": "https://cas.example.org/cas/oidc/accessToken",	"authorization_endpoint": "https://cas.example.org/cas/oidc/authorize",	"userinfo_endpoint": "https://cas.example.org/cas/oidc/profile",	"registration_endpoint": "https://cas.example.org/cas/oidc/register",	"end_session_endpoint": "https://cas.example.org/cas/oidc/logout",	"introspection_endpoint": "https://cas.example.org/cas/oidc/introspect",	"revocation_endpoint": "https://cas.example.org/cas/oidc/revoke",	"backchannel_logout_session_supported": true,	"frontchannel_logout_session_supported": true}
复制代码


对接 nightingale

nightingale 是最优秀的开源监控框架之一,他支持基于 OIDC 协议的 SSO。配置部分在 rdb.yml 的配置文件中的 sso 部分,如下所示:

sso:  enable: true  ssoAddr: "https://cas.example.org/cas/oidc/"  redirectURL: "https://n9e.example.org/auth-callback"  clientId: "client"  clientSecret: "secret"  apiKey: ""  attributes:    dispname: "cn"    email: "mail"    phone: "phone"    im: ""  coverAttributes: false  stateExpiresIn: 300
复制代码

这其中 ssoAddr 配置 OIDC 服务的根路径即可。redirectURL 则是 n9e 前端所在的服务地址的 /auth-callback 路由上。clientIdclientSecret 即是 OIDC 服务所配置的 client 信息。apiKey 是给商业版定制的功能,无需配置。attribtuescoverAttributes 部分就和 LDAP 的配置一样,做属性映射的作用。


完成所有配置后,重启 rdb 服务。注意重启后 ps -ef | grep rdb 看下服务是否正常启动。似乎如果由于 OIDC 对接部分自检无法通过的话,会直接退出 rdb 服务。如果调试期间有问题,建议直接在 n9e 按目录内直接 ./n9e-rdb 启动服务来观察服务启动状态。


如果一切正常,那么当你再次访问夜莺时,他就会自动重定向到你的 OIDC 服务进行认证授权了。并在完成认证后自动进入夜莺。


参考文献



  1. OpenID-Connect

  2. 5 分钟部署一个 OAuth2 服务并对接 Shibboleth-IdP 3.4.6

  3. 15 分钟部署一个 CAS 服务并对接 Shibboleth-IdP 3.4.6

  4. nightingale

以上


发布于: 2021 年 03 月 15 日阅读数: 94
用户头像

冯骐

关注

教育行业码农 2020.06.19 加入

一个教育行业的码农

评论 (1 条评论)

发布
用户头像
2021 年 03 月 15 日 23:32
回复
没有更多了
5 分钟部署一个 OIDC 服务并对接 nightingale