开源IAM系统Casdoor
Casdoor 是一个用户界面优先(对比keycloak,界面的确好看很多)的身份访问管理 (IAM)/单点登录 (SSO) 平台,其 Web UI 支持 OAuth 2.0、OIDC、SAML、CAS、LDAP、SCIM、WebAuthn、TOTP、MFA、RADIUS、Google Workspace、活动目录和 Kerberos。
快速开始
docker 部署
version: '3.1'
services:
casdoor:
image: casbin/casdoor:v1.576.0
environment:
- driverName=mysql
- dataSourceName='root:xxxxxx@tcp(x.x.x.x:3306/)'
基本概念
organizations
组织是Casdoor的基本单位,负责管理用户和应用程序。如果用户登录到某个组织,则他们可以访问属于该组织的所有应用程序,而无需再次登录。
applications
Casdoor 中的每个应用程序都称为“应用程序”。它们不相关且不会互相影响,这意味着您可以根据需要单独部署或停止任何应用程序。
users
providers
casbin
apisix集成
详情参考https://casdoor.org/zh/docs/integration/lua/apisix
authz-casdoor(Casdoor 插件)
简单进行登录接入
"authz-casdoor": {
"_meta": {
"disable": false
},
"callback_url": "https://x.x.x/callback",
"client_id": "aaaaaa",
"client_secret": "xxxxxx",
"endpoint_addr": "https://casdoor.xx.xx"
}
openid-connect(OIDC 插件)
"openid-connect": {
"_meta": {
"disable": false
},
"bearer_only": false,
"client_id": "xxx",
"client_secret": "xxxxxxx",
"discovery": "https://xx.xx.xx/.well-known/openid-configuration",
"introspection_endpoint_auth_method": "client_secret_basic",
"logout_path": "/logout",
"realm": "master",
"redirect_uri": "https://xx.xx.xx/token",
"session": {
"secret": "xxxxxx"
}
}
登录完header里有X-Access-Token,可以使用cardoor sdk直接进行验证X-Access-Token
sdk = casdoor.CasdoorSDK(
"casddor endpoint",
"client_id",
"secret",
cert,
"org",
"app"
)
token = sdk.parse_jwt_token("x-access-token")
# token结构
{'owner': 'test', 'name': 'rokywang', 'id': '02c5a9fa-b9bd-45f0-9d0a-e3905b5dde68', 'displayName': 'rokywang', 'avatar': 'https://cdn.casbin.org/img/casbin.svg', 'email': 'yayruu@example.com', 'phone': '15321069217', 'tokenType': 'access-token', 'nonce': '4e34631a83efd554498b935e4a44b44c', 'scope': 'openid', 'iss': 'https://casdoor.roky.wang', 'sub': '02c5a9fa-b9bd-45f0-9d0a-e3905b5dde68', 'aud': ['709e630a34278b602e80'], 'exp': 1712050076, 'nbf': 1711445276, 'iat': 1711445276, 'jti': 'admin/4e18dd77-b612-4cc9-9059-feca170613ac'}
用户同步
权限配置
casdoor使用casbin作为其底层权限引擎
模型配置
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act