Skip to content
Charles Shao
Go back

authentik 统一身份认证 · OIDC:授权码流程、令牌与配置要点

创建于:
v1.0.0
–views

GitLab、Jenkins、Grafana、Harbor、Argo CD……只要是现代的 Web 应用,几乎没有不支持 OIDC 登录的。在 authentik 统一身份认证 的四种接入方式里,OIDC 永远是第一选择:它不仅让应用彻底碰不到员工的密码,还能顺滑地衔接飞书扫码,甚至能在高危应用的登录环节里再硬生生卡一道 MFA(二次验证)。

本篇我们将扒开 OIDC 登录的整个过程,看看从点击登录到进入页面的几百毫秒里到底发生了什么;同时盘点在 authentik 里对接 OIDC 时必须配对的几个关键参数,以及那些最容易让人踩坑的报错。如果你对 Application、Provider、Binding 等基础概念还不熟悉,建议先扫一眼 架构与接入方式选型。内容基于 authentik 2026.8 的官方文档。

TL;DR

Table of contents

Open Table of contents

1. OIDC 的本质是什么

如果说 OAuth 2.0 是一个授权框架(解决“让应用在用户同意的范围内访问数据”),那么 OpenID Connect(OIDC)就是在 OAuth 2.0 身上套了一层“身份马甲”,专门用来解决“让应用知道目前登录的到底是谁”。

在 OIDC 的世界里,永远有两个核心角色在交互:

有意思的是,在这个统一认证架构里,authentik 其实是个“双面人”:面对 GitLab 时,它是发牌的 OP;但面对飞书时,它又成了信任飞书验证结果的 RP。当员工点击登录 GitLab 时,其实是在经历一场 GitLab → authentik → 飞书的接力跑,验证通过后再原路拿着令牌返回。

2. 登录时究竟发生了什么

现代 Web 应用绝大多数采用的都是授权码模式(Authorization Code Flow):

OIDC 授权码模式时序:浏览器、GitLab、authentik、飞书之间的跳转和令牌交换

一句话总结:授权码走浏览器暴露在明处,令牌走服务器直连藏在暗处。

看着步骤很多,其实只需记住这几个关键点:

3. 令牌与 Scope:应用能拿到什么

换令牌成功后,authentik 到底给了应用什么东西?

令牌作用说明
ID Token核心:告诉应用“登录的是谁”带有签名的 JWT 格式。包含 sub(用户唯一标识)、iss(签发者)、aud(指定给哪个应用)、exp(过期时间),以及按 Scope 返回的属性。
Access Token权限证明:用来调用 userinfo 等 API有效期很短,仅作 Bearer Token 使用。
Refresh Token续期:Access Token 过期后静默换发新 Token注意:从 authentik 2024.2 起默认不再发放。应用必须显式请求 offline_access Scope,且 Provider 层面也要配置相应的 Scope Mapping。

在这个过程中,应用需要通过请求不同的 Scope 来声明自己想要哪些用户信息:

Scope返回的信息
openid必须包含。这标志着当前请求是一个 OIDC 请求而非普通 OAuth2。
profile用户的基本信息:用户名、姓名、所属组等。
email用户的邮箱地址。
entitlements用户在该应用里的权益(用来灵活映射应用内角色)。
offline_access申请颁发 Refresh Token。

其中,entitlements (权益) 是一个极其好用的特性。 举个例子:Grafana 允许全员登录,但只有运维组才是管理员。你不用去 Grafana 里挨个设权限,而是直接在 authentik 给 Grafana 应用建两个权益 Grafana Admins 和 Grafana Editors,分别绑定对应的运维组和研发负责人组。然后在 Grafana 侧这样配置映射规则:

role_attribute_path = contains(entitlements[*], 'Grafana Admins') && 'Admin' || contains(entitlements[*], 'Grafana Editors') && 'Editor' || 'Viewer'

另外要注意一个新版本的行为变更:从 2025.10 版本起,email_verified 字段默认返回 false。有些老派应用比较死板,看到 false 就拒绝登录,或者拒绝按邮箱关联存量账号。遇到这种应用时,需要参考官方文档的 Verify email addresses 章节进行额外配置。

4. authentik 的 OIDC 地址清单

当应用需要手工配置 OIDC 参数时,照着这个表填准没错:

用途对应的 API 地址
自动发现(Discovery)/application/o/<应用 slug>/.well-known/openid-configuration
授权(Authorize)/application/o/authorize/
换令牌(Token)/application/o/token/
获取用户信息(UserInfo)/application/o/userinfo/
退出登录(End Session)/application/o/<应用 slug>/end-session/
签名公钥(JWKS)/application/o/<应用 slug>/jwks/

如果应用比较现代,支持自动发现(Discovery),那你只需要填第一行的地址,再加上 Client ID 和 Client Secret 就够了。 小提示:应用的 Slug(URL 后缀)不能随意起名,绝对避开 authorize、token、device、userinfo 等保留字,否则会和系统的全局路由撞车。

5. 最容易出错的配置要点

在 authentik 里配置 OIDC Provider 时,这几个参数最容易让人栽跟头:

更细粒度的访问控制:如果你想玩点高级的,除了在应用层面绑定用户组,你还可以通过表达式策略(Expression Policy)来拦截特定的 Scope 请求。比如限制只有 ops-admin 组的人才能拿到某个特定的管理员 Scope:

if "my-admin-scope" in request.context["oauth_scopes"]:
    return ak_is_group_member(request.user, name="ops-admin")
return True

6. 排障指南:那些常见的报错

现象最可能的原因
报错 redirect_uri_mismatchRedirect URIs 和浏览器实际发起的回调地址不一致。重点检查 http/https 是否匹配、端口号、以及末尾有没有多或少一个 /。
报错 invalid_issuer应用里填的 Issuer 和 Discovery 接口返回的不一致。如果 Discovery 返回的是 http://,请检查 authentik 的 Base URL 配置以及 Nginx/Ingress 是否正确传递了 X-Forwarded-Proto 等头信息。
令牌验签失败(Invalid Signature)Provider 里没选签名密钥(Signing Key);或者应用服务器的时间不准,导致令牌里的 exp(过期时间)被判为已过期。
应用提示“邮箱未验证”email_verified 字段变成了 false(参考第 3 节的说明)。
登录成功,但在系统里多出一个全新账号应用用来关联老账号的规则(比如是靠用户名还是邮箱)和 authentik 传过去的字段没对上。
请求 Discovery 或 JWKS 时返回 403WAF 或防护规则拦截了服务器端发出的直接请求。请对这几个固定的接口地址开放白名单,不要为了绕过拦截而整体关闭防护。

7. 生产环境的取舍与防坑经验

存量账号迁移才是真正的修罗场。 协议本身很难出 Bug,但 GitLab、Jenkins 里面那些盘根错节的本地老账号极容易翻车。接入 SSO 后,如果系统没认出“新身份”和“老账号”其实是同一个人,就会直接为你创建一个空空如也的重复账号,而你原来的项目、权限、历史记录全被锁死在老账号里。因此,每接一个新系统前,务必先导出存量账号列表和 authentik 进行比对,查清该系统到底是按 sub、用户名还是邮箱来关联身份的,并在深夜找几个真实员工进行小范围试登录。

禁用账号拦得住新人进门,拦不住屋里的人。 员工离职被禁用后,authentik 确实会立刻拒绝他的任何新登录尝试。但他昨天在 GitLab 里建立的会话,只要没过期就依然有效!对于高危系统,务必从两方面补漏:一是缩短会话本身的有效期;二是如果应用支持 Back-channel Logout(后端静默登出),请务必打开,authentik 会在账号被禁用时主动发通知给应用去销毁会话。另外,员工在应用里自行生成的 Personal Access Token 等凭证不受 authentik 控制,必须在系统内单独吊销(完整的离职处理见 架构与接入方式选型)。

扫码的安全上限,就是你飞书账号的安全上限。 既然一切权限的源头都收敛到了飞书扫码,那么飞书侧就必须强制全员开启登录二次验证;而对于 JumpServer、生产环境 Argo CD 这类“只要登进去就能搞破坏”的核弹级应用,必须在扫码之后再强制追加一道 authentik 自己的 MFA(参考第 5 节的配置)。

请放过员工登录,不要把它用来做服务间调用。 OIDC 授权码模式是专门用来解决“活生生的人”登录系统的。如果你的诉求是让微服务 A 去调用微服务 B,请把鉴权任务交给 API 网关 的令牌校验,或者 Service Mesh 的 mTLS。不要试图用 OIDC 去套用这种机器对机器的场景。

8. 参考资料


–views
Share this post on:

Previous Post
authentik 统一身份认证 · 代理认证:用 Forward auth 给 Prometheus 加一道门
Next Post
authentik 统一身份认证 · 架构、核心概念与接入方式选型