Casdoor实战:从统一身份认证到AI网关的部署与集成指南
1. 项目概述:为什么我们需要一个统一的身份认证平台?
最近在重构公司内部几个老系统,每次登录都要记不同的账号密码,开发新应用时用户体系又得从头撸一遍,实在让人头疼。正好看到Casdoor这个开源的身份认证与访问管理平台,它支持OIDC、OAuth 2.0这些标准协议,还能当AI网关用,感觉是个挺有意思的“瑞士军刀”。我花了大概两周时间,从零开始把它部署起来,接入了两个内部系统做单点登录,最后还尝试用它来代理管理我们内部的大模型服务。整个过程踩了不少坑,也总结了一些实战经验,今天就跟大家详细聊聊Casdoor从入门到部署AI网关的全过程。
简单来说,Casdoor的核心价值在于统一身份源和标准化接入。想象一下,公司有OA、CRM、知识库等十多个系统,每个系统都有自己的登录页面和用户表。新员工入职,IT得在十几个地方创建账号;员工离职,又得去十几个地方禁用账号。而Casdoor就是来解决这个问题的,它提供一个中央化的认证服务,其他系统只需要对接Casdoor,用户在一个地方登录,就能访问所有有权限的系统,这就是单点登录。更进一步,Casdoor实现了OIDC这类开放标准,这意味着无论是Java Spring Boot、Python Django还是Go写的服务,只要支持标准协议,都能用同一套方式接入,极大降低了集成成本。至于AI网关,可以把它理解为一个智能的“看门人”,所有对大模型API的请求都先经过它,由它来统一做身份认证、权限控制、流量管理和计费统计,这对于管理内部多个AI服务特别有用。
2. 核心概念与架构拆解:Casdoor是如何工作的?
在动手之前,我们得先搞清楚Casdoor的几个核心概念和它的整体架构,这能帮你理解后续的配置为什么是那样做的,出了问题也知道该从哪儿查。
2.1 核心组件与数据模型
Casdoor的抽象模型很清晰,主要围绕四个核心对象:组织、用户、应用和权限。
- 组织:这是最顶层的容器,通常对应你的公司或一个大的业务部门。所有用户、应用、权限都隶属于某个组织。对于大多数场景,创建一个组织就够了。
- 用户:这个好理解,就是系统的使用者。Casdoor里的用户信息比较全面,除了基础账号密码,还支持手机号、邮箱、多因子认证等。它的设计巧妙之处在于,用户可以直接在Casdoor注册,也可以从已有的数据库、LDAP、GitHub等第三方系统同步过来,作为统一身份源。
- 应用:这是你需要对接Casdoor的每一个具体业务系统。比如你的“内部OA系统”和“项目管理系统”就是两个不同的应用。创建应用时,Casdoor会为你生成一对Client ID和Client Secret,这相当于这个应用在Casdoor的“身份证”,在OAuth2/OIDC流程中至关重要。
- 权限:包括角色和权限规则。你可以创建如“管理员”、“普通员工”、“访客”等角色,然后将这些角色赋予用户。同时,你可以定义非常细粒度的权限规则,控制某个角色能访问哪些API、哪些菜单。这部分在和AI网关结合时,用于控制谁能访问哪个模型,非常关键。
数据存储方面,Casdoor支持多种数据库,如MySQL、PostgreSQL、SQLite。生产环境我强烈推荐用MySQL,稳定性和性能都好得多。它的所有配置,包括上面这些对象,几乎都可以通过Web管理界面操作,这对运维非常友好。
2.2 OIDC单点登录流程详解
单点登录是Casdoor的看家本领,其核心协议是OIDC。OIDC在OAuth 2.0授权框架之上,增加了一个身份层,简单说就是不仅能拿到访问令牌,还能拿到一个包含用户基本信息的ID Token。我们来拆解一个最常用的授权码流程:
- 用户访问应用:用户打开你的业务系统(比如内部Wiki)。
- 重定向到Casdoor登录页:业务系统发现用户未登录,将其浏览器重定向到Casdoor的授权端点,并带上自己的Client ID、想要的权限范围和回调地址。
- 用户在Casdoor认证:用户在Casdoor的统一登录页输入用户名密码(可能还需要MFA验证)。
- Casdoor回调应用:认证成功后,Casdoor将用户浏览器重定向回业务系统指定的回调地址,并附上一个授权码。
- 应用换取令牌:业务系统的后端服务(不能在前端做!)用这个授权码,再加上自己的Client ID和Client Secret,向Casdoor的令牌端点发起请求。
- Casdoor颁发令牌:Casdoor验证无误后,返回ID Token和Access Token。ID Token是JWT格式,可以直接解析出用户的基本信息。
- 应用建立本地会话:业务系统验证ID Token的签名,确认其来自可信的Casdoor后,解析用户信息,并在自己系统内创建本地会话(如设置Cookie),完成登录。
注意:安全的关键在于第5步,必须用后端服务去换令牌,防止Client Secret泄露。同时,应用必须验证ID Token的签名,防止令牌被篡改。
整个过程中,用户只在Casdoor登录一次。之后访问其他接入Casdoor的应用时,会跳过登录页,直接完成上述流程,实现“单点”体验。
2.3 AI网关功能定位
Casdoor的AI网关功能是一个相对较新的特性,它的本质是一个基于身份认证的API代理。在没有它的时候,如果你有多个团队使用不同的AI模型服务,管理起来会很混乱:每个服务有自己的API Key,分发和回收不安全;无法做统一的用量审计和费用分摊;很难做精细的权限控制。
Casdoor AI网关插入到客户端和AI服务提供商之间。所有请求先发到Casdoor网关,网关完成:
- 认证:验证请求者的身份(利用已有的Casdoor用户体系)。
- 鉴权:检查该用户是否有权限访问其请求的AI模型端点。
- 代理与转发:将合法的请求转发给后端的真实AI服务,并将响应返回给客户端。
- 审计与计量:记录每一次请求的详情,用于监控、计费和限流。
这样一来,你只需要在Casdoor里管理一套用户和权限,就能控制对所有AI服务的访问,后端AI服务的API Key也只需在Casdoor网关配置一次,无需分发给每个终端用户,安全性大大提升。
3. 实战部署:从零搭建Casdoor服务
理论讲完了,我们动手搭一个。我的环境是Ubuntu 22.04,用Docker部署,这样最干净也最容易复现。
3.1 环境准备与数据库初始化
首先,确保服务器上安装了Docker和Docker Compose。然后,我们优先准备数据库。
# 创建一个项目目录 mkdir casdoor-deploy && cd casdoor-deploy # 创建docker-compose.yml文件 vim docker-compose.yml下面是docker-compose.yml的内容。这里我同时启动了MySQL和Casdoor本身。注意把MYSQL_ROOT_PASSWORD和MYSQL_DATABASE改成你自己的强密码。
version: '3.8' services: mysql: image: mysql:8.0 container_name: casdoor-mysql restart: always environment: MYSQL_ROOT_PASSWORD: YourStrongRootPassword123! MYSQL_DATABASE: casdoor MYSQL_USER: casdoor MYSQL_PASSWORD: YourStrongCasdoorPassword123! ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql - ./init.sql:/docker-entrypoint-initdb.d/init.sql command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci casdoor: image: casbin/casdoor:latest container_name: casdoor-app restart: always depends_on: - mysql ports: - "8000:8000" environment: RUNNING_IN_DOCKER: "true" DATABASE_TYPE: "mysql" DATABASE_HOST: "mysql" DATABASE_PORT: "3306" DATABASE_USER: "casdoor" DATABASE_PASSWORD: "YourStrongCasdoorPassword123!" DATABASE_NAME: "casdoor" volumes: - ./conf/app.conf:/conf/app.conf这里有几个关键点:
- 字符集:MySQL的命令参数里指定了
utf8mb4,这是为了支持存储Emoji等特殊字符,避免以后出现乱码问题。 - 初始化脚本:我挂载了一个
init.sql到/docker-entrypoint-initdb.d/目录。MySQL容器启动时会自动执行这个目录下的SQL文件。我们可以在这里创建表,但注意:Casdoor其实会在首次启动时自动建表。所以这个init.sql主要用于创建额外的数据库或用户,如果只是用默认的casdoor库,这个文件可以留空或删除相关行。 - 配置文件挂载:我们把本地的
./conf/app.conf挂载到容器里,这样方便修改配置而不用重建镜像。
接下来,创建配置目录和文件:
mkdir conf vim conf/app.conf基础的app.conf配置如下,重点是数据库连接和初始管理员账号:
appname = casdoor httpport = 8000 runmode = prod driverName = mysql dataSourceName = casdoor:YourStrongCasdoorPassword123!@tcp(mysql:3306)/casdoor?charset=utf8mb4&parseTime=True&loc=Local # 初始化一个管理员账号,首次登录后请立即修改密码! initDataFile = "./init_data.json"init_data.json文件定义了初始的组织、用户和应用。你需要从Casdoor的GitHub仓库找到示例文件并修改,特别是管理员用户的密码。出于安全考虑,这里不展示完整内容,但请务必在首次登录后修改这个初始密码。
3.2 启动服务与初始配置
配置完成后,一键启动:
docker-compose up -d用docker-compose logs -f casdoor查看日志,等到出现HTTP Server Running on http://0.0.0.0:8000之类的字样,就说明启动成功了。打开浏览器,访问http://你的服务器IP:8000,应该能看到Casdoor的登录界面。
用你init_data.json里设置的管理员账号登录。进入后台管理页面,第一件事就是修改管理员密码,并开启双因素认证。
接下来,建议你按照这个顺序进行配置:
- 检查组织:确认默认组织(如
built-in)存在。 - 创建测试用户:在“用户”页面,手动创建几个测试用户,比如
zhangsan、lisi。 - 创建第一个应用:这是对接你业务系统的关键。
- 进入“应用”页面,点击“新增”。
- 填写应用名称,如“内部Wiki系统”。
- 重定向URL:这是你业务系统接收授权码的回调地址,必须准确。例如
http://your-wiki.com/api/casdoor/callback。本地测试可以用http://localhost:8080/callback。 - 点击保存后,系统会生成
Client ID和Client Secret,务必妥善保存,后面集成时会用到。
4. 应用集成实战:让SpringBoot应用接入Casdoor单点登录
现在Casdoor服务跑起来了,我们让它真正发挥作用,接一个Spring Boot应用进去。我会用一个最简单的Spring Boot Web项目来演示。
4.1 搭建SpringBoot演示应用
先用Spring Initializr创建一个新项目,依赖选择Spring Web和Spring Security。然后,我们需要添加对OIDC客户端的支持。在pom.xml中添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency>4.2 配置OIDC客户端
核心配置都在application.yml里:
spring: security: oauth2: client: registration: casdoor: # 这个provider名称可以自定义 provider: casdoor client-id: ${CASDOOR_CLIENT_ID} # 从Casdoor应用页面获取 client-secret: ${CASDOOR_CLIENT_SECRET} # 从Casdoor应用页面获取 scope: openid,profile,email # 申请获取的信息范围 redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}" # Spring Security默认回调路径 authorization-grant-type: authorization_code client-name: Casdoor provider: casdoor: # 替换为你的Casdoor服务地址和应用名称 issuer-uri: http://你的casdoor服务器:8000 # Spring Security 默认的端点路径,Casdoor是兼容的 user-name-attribute: preferred_username # 映射Casdoor的用户名字段实操心得:
issuer-uri是关键。Spring Security会向{issuer-uri}/.well-known/openid-configuration发起请求,自动发现端点信息。确保你的Casdoor能在外网或测试环境访问到这个发现端点。如果网络不通,你就需要手动配置authorization-uri,token-uri,user-info-uri等所有端点,非常麻烦。
4.3 编写安全配置与控制器
创建一个安全配置类,来定义哪些路径需要保护,登录成功后跳转到哪里:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authz -> authz .requestMatchers("/", "/public/**").permitAll() .anyRequest().authenticated() // 其他所有请求都需要认证 ) .oauth2Login(oauth2 -> oauth2 .defaultSuccessUrl("/home", true) // 登录成功后跳转到/home ) .logout(logout -> logout .logoutSuccessUrl("/") ); return http.build(); } }再创建一个简单的控制器,展示用户信息:
@Controller public class HomeController { @GetMapping("/home") public String home(Model model, @AuthenticationPrincipal OidcUser user) { if (user != null) { model.addAttribute("name", user.getFullName()); model.addAttribute("email", user.getEmail()); model.addAttribute("claims", user.getClaims()); } return "home"; // 对应一个Thymeleaf或HTML页面 } }4.4 测试单点登录流程
- 启动你的Spring Boot应用(默认端口8080)。
- 访问
http://localhost:8080/home,此时会被重定向到Casdoor的登录页面。 - 使用你在Casdoor中创建的测试用户登录。
- 登录成功后,会自动跳转回
/home页面,并显示从Casdoor获取的用户信息。
至此,单点登录集成基本完成。你可以看到,我们自己的应用没有写任何用户注册、登录的代码,全部交给了Casdoor和Spring Security OAuth2 Client来处理,非常清爽。
5. 进阶配置:打造AI网关服务
单点登录搞定后,我们来看看更“时髦”的AI网关功能。假设我们内部使用了OpenAI的API和另一个开源的ChatGLM模型,现在想通过Casdoor统一管理访问。
5.1 启用并配置AI网关模块
Casdoor的AI网关功能默认可能未开启。你需要确认使用的是较新版本,并在管理界面查看是否有“AI Providers”或“网关”相关菜单。
配置步骤通常如下:
- 添加AI提供商:在管理界面,找到AI网关配置处,添加一个新的提供商。比如“OpenAI”。
- 类型:选择
OpenAI。 - API密钥:填入你从OpenAI官网获取的组织级API Key。注意:这里用的是服务端密钥,而不是分发给最终用户的。
- API地址:一般用默认的
https://api.openai.com/v1即可,如果你用的是Azure OpenAI或代理,需要修改。 - 限流规则:可以设置每分钟/每天的请求次数上限。
- 类型:选择
- 创建AI模型:为这个提供商创建具体的模型,比如
gpt-4、gpt-3.5-turbo。这里可以设置该模型单独的调用成本(用于计费)、上下文长度等参数。 - 配置权限:这是核心。在Casdoor的权限管理中,创建新的权限规则,将“用户/角色”与“AI模型”关联起来。例如,你可以创建一个规则:“角色为
developer的用户,可以访问gpt-4模型,每日上限100次请求”。
5.2 客户端如何调用网关API
配置好网关后,客户端就不再直接请求api.openai.com了,而是请求你的Casdoor网关端点。假设你的Casdoor网关地址是http://your-casdoor.com:8000。
调用方式一:模拟OpenAI SDK(推荐)Casdoor AI网关的API设计通常兼容OpenAI的格式。这意味着,你可以在客户端使用OpenAI的官方SDK,只需要把base_url和api_key替换掉。
# Python示例,使用openai库 import openai # 原来的直接调用OpenAI # openai.api_key = "sk-your-openai-key" # openai.api_base = "https://api.openai.com/v1" # 现在改为调用Casdoor AI网关 openai.api_key = "your-casdoor-access-token" # 这里填的是用户的Casdoor访问令牌,不是OpenAI的key! openai.api_base = "http://your-casdoor.com:8000/api/ai-proxy" # 网关API地址 response = openai.ChatCompletion.create( model="gpt-4", # 这个模型名是在Casdoor里配置的 messages=[{"role": "user", "content": "你好,请介绍一下你自己。"}] ) print(response.choices[0].message.content)调用方式二:直接发送HTTP请求你也可以用最原始的HTTP请求方式,网关的请求/响应格式与OpenAI兼容。
curl -X POST http://your-casdoor.com:8000/api/ai-proxy/chat/completions \ -H "Authorization: Bearer YOUR_CASDOOR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "Hello!"}] }'关键点:这里的
Authorization头承载的Bearer令牌,是用户通过Casdoor OIDC登录后获取的Access Token,而不是AI服务商的API Key。网关收到请求后,会验证这个令牌的有效性,检查用户权限,然后用自己的配置的API Key去请求真正的AI服务。
5.3 实现效果与监控
配置完成后,你就拥有了一个具备以下能力的AI访问中台:
- 统一入口:所有AI请求走一个地址。
- 身份与权限:基于公司现有账号体系控制AI访问权限。
- 成本管控:可以设置用户/部门级的调用额度,防止滥用。
- 审计日志:在Casdoor后台可以查看所有AI调用记录,包括谁、什么时候、调用了什么模型、消耗了多少Token。
- 负载均衡与高可用:未来可以在网关层面为同一个模型配置多个后端API Key,实现负载均衡和故障转移。
6. 生产环境部署的注意事项与踩坑记录
把Casdoor用于生产环境,有几个坑是必须要提前知道的。
6.1 安全性加固
- HTTPS是必须的:绝不要在公网用HTTP运行Casdoor。使用Nginx或Traefik等反向代理,配置SSL证书。在Casdoor的应用配置中,重定向URL也必须使用HTTPS地址。
- 保护Client Secret:
Client Secret相当于应用密码,必须存储在环境变量或配置服务器中,绝不能提交到代码仓库。在Spring Boot配置中,我用了${CASDOOR_CLIENT_SECRET}就是从环境变量读取。 - 定期轮转密钥:Casdoor支持为应用重新生成Client Secret。制定一个策略,定期轮转,并确保所有集成的应用同步更新。
- 细粒度权限控制:不要滥用管理员权限。根据最小权限原则,为不同运维人员创建不同角色。
- 开启审计日志:Casdoor会记录重要操作,定期检查这些日志,有助于发现异常行为。
6.2 性能与高可用
- 数据库优化:生产环境务必使用独立的MySQL或PostgreSQL,并做好性能调优(如索引优化)。定期清理过期的令牌和日志表。
- 无状态部署:Casdoor本身是无状态的,会话信息可以存储在Redis中。这方便你部署多个实例,用负载均衡器引流,实现高可用。配置
app.conf中的redis相关设置即可。 - 资源监控:监控Casdoor容器的CPU、内存使用情况,以及数据库连接数。
6.3 常见问题排查
- 登录后无限重定向:
- 最常见原因:应用配置中的
重定向URL与Spring Security实际接收回调的URL不匹配。仔细检查Casdoor应用配置里的Redirect URL和代码中application.yml里的redirect-uri模板,确保域名、端口、路径完全一致。本地开发时,http://localhost和http://127.0.0.1也被视为不同的域名。 - 检查Cookie作用域:如果你的Casdoor和应用不在同一个顶级域名下,浏览器可能不会发送Cookie。需要确保它们在相同的父域名下,或者配置跨域资源共享。
- 最常见原因:应用配置中的
- 获取用户信息为null或不全:
- 检查Casdoor中该用户的
邮箱、显示名等字段是否已填写。 - 检查OIDC Scope是否申请了
profile和email。 - 在Spring Security配置中,检查
user-name-attribute映射是否正确。可以尝试改成sub或name看看。
- 检查Casdoor中该用户的
- AI网关调用返回403或401:
- 403:通常是权限问题。确认该用户是否被赋予了访问目标AI模型的角色或权限。
- 401:令牌无效或过期。确认客户端使用的
Access Token是有效的,且没有过期。Access Token通常有较短的有效期,需要实现令牌刷新逻辑。 - 查看Casdoor网关的日志,通常会有更详细的错误信息。
6.4 与现有系统集成的思考
如果你的公司已经有LDAP或Active Directory,Casdoor可以作为桥梁。你可以配置Casdoor从LDAP同步用户信息,这样用户可以用AD账号登录,而权限管理仍在Casdoor内进行,实现了用户源统一和管理灵活性的平衡。
对于老旧系统,如果不支持OIDC标准协议,Casdoor也提供了CAS、SAML等传统协议的支持,或者最不济,可以通过反向代理注入认证信息的方式实现单点登录,不过这需要更复杂的配置。
部署Casdoor并成功接入一两个核心应用后,你会明显感受到运维效率的提升。新应用上线,身份认证部分几乎可以忽略不计。AI网关的引入,更是让混乱的AI服务调用变得井然有序。当然,它也不是银弹,对于超大规模、有极端性能要求的场景,可能需要更专业的企业级IAM产品。但对于大多数中小团队和项目而言,Casdoor这套开源组合拳,无论是从功能完整性、协议标准性还是社区活跃度来看,都是一个非常值得投入学习和使用的解决方案。
