尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

开源IAM平台authentik:统一认证、SSO与零改造接入实战

开源IAM平台authentik:统一认证、SSO与零改造接入实战 如果你负责过几套内部系统大概率经历过这样的场景GitLab 一套账号、Grafana 一套账号、Jenkins 又一套账号。新员工入职时运维要挨个系统开通权限离职时又要记着去每个平台注销。密码规则不统一审计日志更是零散分布在各套系统里。很多人第一反应是“上 SSO”可一搜方案就陷入选择困难商业产品按用户数收费开源项目要么配置复杂到接近重写一个认证系统要么只能覆盖单一协议。authentik 是这一类问题中值得关注的开源答案。它把自己定位为“基础设施里的身份认证提供商Identity ProviderIdP”把单点登录SSO、多因素认证MFA、用户与权限管理、应用接入、审计日志等能力打包成一个可以部署在自有服务器上的开源访问管理平台。从项目形态看它真正想降低的不是“登录框”的成本而是企业自建统一认证体系的整体工程成本。需要先澄清一个常见的误区项目 GitHub 组织名是 goauthentik但这并不代表它用 Go 语言编写。authentik 的后端基于 Python/Django整个项目是一个偏“全家桶”形态的开源 IAM 平台。很多人看到 goauthentik 就以为是一个 Go 写的轻量认证组件实际动手才发现概念和组件比想象中多。这篇文章围绕三个核心问题展开authentik 到底解决了什么痛点和直接用 Spring Security、自己写登录逻辑、或者用商用 IdP 相比差异在哪里作为一个初学者如何用最小成本部署 authentik并完成两个真实接入场景标准 OIDC 应用接入以及不改后端代码、用 Proxy Provider 保护老系统如果要把 authentik 放到生产环境哪些坑必须提前避开。文章目标是让你读完能直接动手跑通一条完整链路而不是停留在概念层面。1. 这篇文章真正要解决的问题先明确一点authentik 不是又一个“登录组件”。它解决的是企业内部应用越来越多之后账号、密码、权限、审计这四件事失去控制的系统性难题。1.1 统一认证的痛点在哪里没有统一认证时每一套系统都会各自维护一套用户表。这个模式在系统数量少于三个时是高效的一旦系统数量变多问题就会集中爆发账号数据不一致。同一个员工在 A 系统叫zhangsan在 B 系统叫zhang.san在 C 系统用的是邮箱前缀。你无法确认这些是不是同一个人。密码策略无法统一。有的系统要求 8 位密码有的要求大小写加特殊字符有的干脆明文存储。密码泄漏后攻击者可以用同一套凭据去撞库其他系统。权限管理靠管理员手工操作。每次入职、离职、转岗管理员都要逐个系统更新权限操作量大还容易漏。离职员工的账号如果没及时注销就是安全死角。审计追踪缺失。出了问题要追溯“谁在什么时间访问了什么”每套系统都各查各的效率极低。这些问题本质上不是“写不好登录功能”而是“身份数据散落在多个孤岛里”。authentik 这类工具的核心价值就是把这些孤岛的身份数据统一收口然后基于同一个身份源对外提供标准和统一的认证、授权能力。1.2 authentik 的定位authentik 的官方定位是 Open Source Identity Provider in your infrastructure。它覆盖的身份认证和访问管理能力包括单点登录SSO用户只需要登录一次就能访问所有接入的应用多因素认证MFA内置 TOTP、WebAuthn 等认证方式可以在安全要求高的场景下强制开启用户与组管理提供管理界面和 API支持用户的创建、分组、属性管理应用接入通过 OIDC/OAuth2、SAML、LDAP、RADIUS 等标准协议对外提供认证能力访问策略Policy管理员可以通过策略控制“谁能访问哪些应用”而不用把权限逻辑散落在各个业务系统里审计日志登录事件、授权事件、应用访问事件都会被记录方便追溯。它的核心设计理念是“模块化”。登录不是写死在代码里的逻辑而是由若干个 Flow、Stage、Policy 组合出来的流程。这种设计让 authentik 比传统的固定登录流程更灵活但同时也带来了更高的学习成本。1.3 什么样的团队适合 authentik从实际场景看适合引入 authentik 的团队通常有这些特征内部有多个 Web 系统但还没有统一身份源希望在一个可控范围内做单点登录而不是直接购买按用户计费的商业 IAM 服务有 Docker/容器化运维能力能够接受一定的运维成本有改造部分应用的意愿但也有一些老系统短期内无法改代码需要一种“不改应用也能加认证”的方案。反过来如果团队只有一两个系统或者只是想快速给某个临时项目加一个 OAuth2 登录不推荐上来就部署 authentik。它更适合作为基础设施长期运营而不是一个临时工具。2. authentik 的核心概念与设计思想动手部署之前先建立几个关键概念。这些概念之间是层层套用的关系理解了它们后面的配置操作就不会觉得是“填表”。2.1 基础术语IdP 与 IAMIdPIdentity Provider身份提供商负责验证用户身份并发放身份凭证的系统。OIDC 协议里的 Authorization Server、SAML 协议里的 IdP 角色都属于这类。IAMIdentity and Access Management身份与访问管理比 IdP 更大的范畴除了认证还包括用户管理、权限管理、审计等。authentik 官方常把两者放在一起介绍。简单理解IdP 解决“你是谁”的问题IAM 在“你是谁”之外还要回答“你有权做什么”以及“你做了什么”。2.2 authentik 中的核心对象在 authentik 管理界面里你一定会反复看到这几个词Flow、Stage、Policy、Provider、Application、Outpost。它们的关系可以用一句话概括用户访问 ApplicationApplication 绑定 ProviderProvider 负责用标准协议和业务系统对接而认证和授权的具体过程由 Flow、Stage、Policy 组合完成Outpost 则在运行时承载访问策略的执行。各概念的解释如下表概念通俗解释典型例子Flow认证流程的编排单元登录流程、注册流程、密码重置流程Stage流程中的一个具体步骤输入用户名密码、验证 MFA、展示授权确认页Policy判断“是否允许”的规则只有属于某个组的用户才能登录Provider一个对外协议接入点OIDC Provider、SAML Provider、LDAP Provider、Proxy ProviderApplication一个受保护的业务应用GitLab、Grafana、某个内部管理系统Outpost运行时执行访问策略的组件Proxy Outpost、LDAP Outpost2.3 Flow 和 Stage 是最容易理解偏差的地方很多新手以为 authentik 的 Flow 就是“登录页”这是不准确的。Flow 更像一条流水线Stage 是流水线上的工位。比如一个“登录”流程可以编排成UserLoginStage判断当前是否已经登录PasswordStage校验账号密码AuthenticatorValidateStage如果用户开启了 MFA则验证动态口令UserWriteStage把用户状态写入会话。这样的设计带来一个很大的好处authentik 的登录流程不是写死的而是可以编排的。同一个实例下可以针对不同应用、不同用户组设置不同严格程度的流程。比如内部管理系统强制走 MFA而访客 Wi-Fi 门户只需要密码。这也是 authentik 与很多“登录组件”最大的差异它不是给你一个固定的登录页而是给你一套可以自由拼接的认证积木。2.4 再理解 Provider 和 Application在 authentik 里Provider 是“对外提供认证能力”的一端Application 是“被保护的业务应用”。一个 Application 必须绑定一个 Provider才能真正生效。这里的常见误解是创建 Provider 和 Application 时需要“业务系统配合”。实际上Provider 创建后业务系统只需要拿到 Client ID、Client Secret、Issuer URL 等参数就能通过标准协议接入。业务系统不需要把用户数据同步给 authentik也不需要理解 authentik 内部的结构。2.5 和 Keycloak 怎么选提到开源 IAM几乎绕不开 Keycloak。两者的定位重叠度很高但设计取向有明显差异这也是很多人纠结的地方。对比维度authentikKeycloak项目定位身份认证 访问管理强调流程可编排老牌 IdP侧重标准协议实现部署形态容器优先Docker 体验流畅Java 应用功能相对集中协议支持OIDC/OAuth2、SAML、LDAP、RADIUS、ProxyOIDC/OAuth2、SAML、LDAP 等老应用接入原生支持 Proxy Provider可零改造接入需要借助额外网关或改造应用学习曲线概念多初始配置较复杂概念同样多但社区资料更丰富社区成熟度相对年轻但迭代活跃社区大文档和案例更成熟从选型角度我的建议是如果团队已经有较成熟的 Java 技术栈且重点需求是标准协议接入Keycloak 是稳妥选择如果希望把“老系统零改造接入认证”也纳进来且更看重现代化界面和流程编排能力authentik 更贴合。3. 环境准备与安装部署从这一章开始进入实操。先部署一个最小可用的 authentik 实例。3.1 前置条件Linux 服务器或本地开发机Docker 20.10 以上docker compose v2 插件建议至少 2 核 4GB 内存磁盘 20GB 以上宿主机开放端口9000HTTP、9443HTTPS。注意以下部署方案用于本地或测试环境。如果用于生产建议把9000、9443端口放在 Nginx 或负载均衡器后面并使用正式域名和证书。3.2 目录结构建议在一个干净目录下操作authentik/ ├── docker-compose.yml ├── .env ├── media/ ├── custom-templates/ └── certs/media目录存放用户上传的媒体文件custom-templates用于自定义主题或邮件模板certs用于存放证书。这些目录需要预先创建。mkdir -p authentik/{media,custom-templates,certs} cd authentik3.3 docker-compose.yml下面是一个最小可用的 compose 文件包含 PostgreSQL、Redis、Server、Worker 四个服务。为了便于教学这里省略了独立的 Proxy Outpost 容器后面的 Proxy 场景再单独补上。# 文件路径authentik/docker-compose.yml version: 3.8 services: postgresql: image: docker.io/library/postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: authentik POSTGRES_USER: authentik POSTGRES_PASSWORD: ${AUTHENTIK_POSTGRESQL__PASSWORD} volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: [CMD-SHELL, pg_isready -d authentik -U authentik] interval: 10s timeout: 5s retries: 5 redis: image: docker.io/library/redis:7-alpine restart: unless-stopped command: --appendonly yes volumes: - redisdata:/data healthcheck: test: [CMD, redis-cli, ping] interval: 10s timeout: 5s retries: 5 server: image: ghcr.io/goauthentik/server:${AUTHENTIK_VERSION:-latest} restart: unless-stopped command: server environment: AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY} AUTHENTIK_POSTGRESQL__HOST: postgresql AUTHENTIK_POSTGRESQL__USER: authentik AUTHENTIK_POSTGRESQL__NAME: authentik AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRESQL__PASSWORD} AUTHENTIK_REDIS__HOST: redis ports: - ${AUTHENTIK_PORT_HTTP:-9000}:9000 - ${AUTHENTIK_PORT_HTTPS:-9443}:9443 volumes: - ./media:/media - ./custom-templates:/templates depends_on: postgresql: condition: service_healthy redis: condition: service_healthy worker: image: ghcr.io/goauthentik/server:${AUTHENTIK_VERSION:-latest} restart: unless-stopped command: worker environment: AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY} AUTHENTIK_POSTGRESQL__HOST: postgresql AUTHENTIK_POSTGRESQL__USER: authentik AUTHENTIK_POSTGRESQL__NAME: authentik AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRESQL__PASSWORD} AUTHENTIK_REDIS__HOST: redis volumes: - ./media:/media - ./custom-templates:/templates - ./certs:/certs depends_on: postgresql: condition: service_healthy redis: condition: service_healthy volumes: pgdata: redisdata:3.4 .env 文件在authentik目录下创建.env文件。AUTHENTIK_SECRET_KEY和数据库密码必须修改不要使用默认值。# 文件路径authentik/.env AUTHENTIK_SECRET_KEYplease-change-me-to-a-random-64-character-string AUTHENTIK_POSTGRESQL__PASSWORDplease-change-me-db-password AUTHENTIK_PORT_HTTP9000 AUTHENTIK_PORT_HTTPS9443 AUTHENTIK_VERSION2024.8说明AUTHENTIK_SECRET_KEY是 authentik 的核心密钥用于签名 Session、Token 等务必使用足够长的随机字符串且每次升级保持一致AUTHENTIK_VERSION使用日期版本号。上面示例是2024.8你可以到官方 GitHub Releases 查询最新的日期版本替换后重新执行 compose 命令即可如果宿主机 9000 或 9443 已经被占用可以修改AUTHENTIK_PORT_HTTP和AUTHENTIK_PORT_HTTPS。3.5 启动服务docker compose up -d等待服务启动后查看日志docker compose logs -f server看到类似Listening at: http://0.0.0.0:9000的日志说明服务已经启动。3.6 初始化管理员浏览器访问http://localhost:9000/if/flow/initial-setup/正常情况下会显示初始设置页面需要设置管理员邮箱和密码。创建完成后就可以用管理员账号登录管理界面。管理界面入口通常是http://localhost:9000/if/admin/这里真正容易踩坑的地方是初始化页面必须是第一次访问才会出现。如果之前已经初始化过再进入同一个地址可能直接跳转到登录页。此时不需要重新初始化直接用已创建的管理员账号登录即可。4. 场景一用 OIDC 接入一个标准业务系统第一个真实场景把 authentik 作为 IdP接入一个支持 OIDC 的业务系统。这里以 Spring Boot Spring Security 为例因为这是 Java 后端最常见的接入方式。4.1 在 authentik 中创建 OAuth2/OpenID Connect Provider进入 Admin 界面左侧菜单选择Applications - Providers点击Create。关键字段如下Name给 Provider 起一个可读名字例如my-app-oidcClient Type选择Confidential这种类型适合后端应用需要依赖 Client SecretClient ID / Client Secret可自动生成也可以手动填写Redirect URIs必填项填写业务系统完成 OIDC 登录后的回调地址。Spring Boot 默认回调格式是http://localhost:8080/login/oauth2/code/authentik保存后在 Provider 详情页可以看到 authentik 自动生成的 Issuer URL格式大致为http://localhost:9000/application/o/my-app/这个地址要记下来后面配置业务系统时会用到。这里的my-app通常是 Application Slug 相关的路径具体以管理界面实际显示为准。4.2 创建 Application 并绑定 Provider在Applications - Applications页面点击CreateNamemy-appSlugmy-appProvider选择刚刚创建的my-app-oidcLaunch URL可以填写业务系统的首页地址例如http://localhost:8080。保存后OIDC 接入需要的信息就齐了Issuer URL: http://localhost:9000/application/o/my-app/ Client ID: 从上一步详情页获取 Client Secret: 从上一步详情页获取 Redirect URI: http://localhost:8080/login/oauth2/code/authentik4.3 在 Spring Boot 中配置 OIDC Client假设你已经有一个 Spring Boot 3 项目并且引入了 Spring Security 相关依赖。在application.yml中加入如下配置# 文件路径src/main/resources/application.yml spring: security: oauth2: client: registration: authentik: provider: authentik client-id: ${AUTHENTIK_CLIENT_ID} client-secret: ${AUTHENTIK_CLIENT_SECRET} authorization-grant-type: authorization_code client-authentication-method: client_secret_basic redirect-uri: {baseUrl}/login/oauth2/code/authentik scope: - openid - profile - email provider: authentik: issuer-uri: http://localhost:9000/application/o/my-app/对应地在环境变量或配置中心里设置AUTHENTIK_CLIENT_IDyour-client-id AUTHENTIK_CLIENT_SECRETyour-client-secret这段配置的工作方式是Spring Boot 启动时会通过issuer-uri自动拉取 authentik 的 OIDC 发现文档用户访问受保护接口时Spring Security 将其重定向到 authentik 的登录页面authentik 验证通过后通过授权码模式把用户重定向回 Spring Boot 应用Spring Boot 用client-secret换取 Token并拿到用户身份信息。4.4 启动并验证启动 Spring Boot 应用后访问任意受保护的接口例如http://localhost:8080/。浏览器会自动跳转到 authentik 登录页。输入管理员账号密码后再跳回业务应用说明 OIDC 接入成功。如果跳回时出现400或invalid_request优先检查两处Redirect URI 是否完全一致包括端口和路径Client Secret 是否填写正确。5. 场景二用 Proxy Provider 保护未改造的 Web 应用第二个场景是 authentik 区别于一众 IdP 的亮点不需要改业务代码就能给老系统加上登录和权限校验。假设内部有一个古老的 Web 服务它本身没有用户体系或者只支持简单的 Basic Auth运维不想改源码。这时候可以用 authentik 的 Proxy Provider。5
返回列表