Authelia OpenID Connect 1.0 Provider 配置完全指南:从 HMAC 密钥到授权策略
【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia
Authelia 支持以OpenID Connect 1.0 Provider(授权服务器/身份提供方)的身份运行,让任何实现了 OpenID Connect Relying Party(依赖方)角色的应用——例如 Grafana、Nextcloud、Traefik 等——像接入社交媒体登录一样接入你的统一认证体系。本文以仓库内 provider.md 文档为骨架,结合 schema 定义 与 validator 实现 的源码证据,逐项讲解identity_providers.oidc下的全部配置项、默认值与安全约束,让你能够独立完成从密钥生成、JWKS 配置到授权策略与令牌生命周期的完整落地。
角色定位:Authelia 是 Provider,不是 Relying Party
在 OpenID Connect 1.0 生态中,Authelia 目前只承担Provider角色(开放 beta 状态的功能),即作为认证与授权的"服务端";它不实现 Relying Party 角色——也就是说,你不能让 Authelia 反过来去对接 GitHub、Google 等第三方 Provider 完成登录(项目目前也没有这方面的计划)。
这意味着你的应用(Relying Party)需要调用 Authelia 暴露的授权端点、令牌端点与发现端点,用户在 Authelia 的界面上完成单因素/双因素认证与授权同意后,获得id_token、access_token等令牌。Authelia 已通过OpenID Certified™认证,符合 OpenID Connect™ 协议规范;关于该功能的状态,可参见 集成文档 与 roadmap。
单个客户端(client)的注册与配置不在本文范围,请参阅 OpenID Connect 1.0 Clients 文档。
配置总览:一个最小可用示例
所有配置都位于identity_providers.oidc键下。下面是仓库文档给出的完整示例骨架,其中hmac_secret与jwks是必填项(required="yes"),其余均有默认值:
identity_providers: oidc: hmac_secret: 'this_is_a_secret_abc123abc123abc' jwks: - key_id: 'example' algorithm: 'RS256' use: 'sig' key: | -----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY----- certificate_chain: | -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- enable_client_debug_messages: false minimum_parameter_entropy: 8 enforce_pkce: 'public_clients_only' enable_pkce_plain_challenge: false enable_jwt_access_token_stateless_introspection: false discovery_signed_response_alg: 'none' discovery_signed_response_key_id: '' require_pushed_authorization_requests: false authorization_policies: policy_name: default_policy: 'two_factor' rules: - policy: 'deny' subject: 'group:services' networks: - '192.168.1.0/24' - '192.168.2.51' lifespans: access_token: '1h' authorize_code: '1m' id_token: '1h' refresh_token: '90m' claims_policies: policy_name: id_token: [] access_token: [] id_token_audience_mode: 'specification' custom_claims: claim_name: name: 'claim_name' attribute: 'attribute_name' scopes: scope_name: claims: [] cors: endpoints: - 'authorization' - 'token' - 'revocation' - 'introspection' allowed_origins: - 'https://example.com' allowed_origins_from_client_redirect_uris: false对应的 Go 结构体定义在 identity_providers.go,其中每个字段的koanf/yaml标签即与上述键一一对应。在启动时,validator 的validateOIDC会执行默认值填充与合法性校验:例如未配置任何clients会直接报错(errFmtOIDCProviderNoClientsConfigured),未配置任何私钥同样无法通过校验。
必填基础:hmac_secret 与 jwks
hmac_secret:JWT 签名的 HMAC 基础密钥
hmac_secret(字符串,必填,敏感值)用于为 JWT 提供 HMAC 签名基础。配置时需要注意:
- 你提供的字符串会被SHA256 哈希(符合 RFC6234)为固定字节串,以满足签名格式要求——这一点在源码中体现为
GlobalSecret: []byte(utils.HashSHA256FromString(config.HMACSecret))(见 config.go); - 官方强烈建议使用 64 位或更长的 随机字母数字字符串,例如:
# 使用 Authelia 自带的 crypto 子命令生成 authelia crypto rand --length 64 --charset alphanumeric # 或者使用 openssl openssl rand -hex 64jwks:签发者 JSON Web Key 列表
jwks(列表,必填)是签发者(issuer)使用的 JSON Web Key 集合。核心约束与规则:
- 至少一个 RSA 私钥,且必须配置
RS256算法(validator 中若ResponseObjectSigningAlgs不包含 RS256 会直接报错,见 identity_providers.go); - 除 RSA 外,还支持其他 RSA 变体、ECDSA、Ed25519(兼容标识
EdDSA)以及 ML-DSA 等后量子算法; - 默认键的判定规则:每个算法的第一把键是"默认键"。例如客户端配置了
id_token_signed_response_alg: ES256但未指定key_id,则使用列表中第一把 ES256 键; - 若客户端未指定
key_id,则使用该算法默认键;客户端指定key_id时需与列表中的key_id完全匹配。
key_id
可选,默认值为"公钥 SHA256 指纹的十六进制编码前 7 个字符 + 连字符 + 小写算法名",例如abc1234-rs256。一般不建议手动指定,除非自动生成的 id 发生冲突。若提供,必须满足:
- 唯一,且长度 ≤ 100 字符(推荐 < 15);
- 匹配正则
^a-zA-Z0-9([a-zA-Z0-9]))?$——即以字母数字开头和结尾,中间只含 RFC3986 非保留字符。validator 中使用reOpenIDConnectKID校验,超过 100 字符会报长度错误(见 identity_providers.go)。
use
可选,默认sig。合法值为sig(签名)与enc(加密)。
algorithm
可选(多数情况下可根据密钥类型自动探测),默认RS256。可用值以集成文档的 Response Object 表格 为准:Algorithm列列出受支持算法,Key列说明算法对密钥类型的要求,JWK Default Conditions列说明该算法成为默认算法的条件。要点:
- 已废弃的
EdDSA标识符可作为Ed25519的别名被接受(为兼容实现 RFC8037 的客户端),但推荐使用Ed25519; - 至少要提供一把 RS256 键。
key
必填。签发者用于对 JWT 签名/加密的私钥。注意:常见的密钥生成方法会同时输出私钥与公钥,但本选项只接受私钥(公钥相关配置见下文certificate_chain,多数情况下并不需要)。私钥必须满足:
- PEM 块、DER base64 编码(RFC4648);
- RSA 私钥:符合 PKCS#8 或 PKCS#1 编码,密钥长度 ≥ 2048 位(validator 中
key.Size() < 256即 2048 位以下会报错,见 identity_providers.go); - ECDSA 私钥:符合 PKCS#8 或 SECG1 编码,曲线为 P-256 / P-384 / P-512;
- 若提供了
certificate_chain,链中首张证书必须包含与该私钥匹配的公钥数据。
生成方式可参考 Generating an RSA Keypair 指南:
# 使用 Authelia CLI authelia crypto pair rsa generate # 或使用 openssl openssl genrsa -out private.pem 2048 openssl rsa -in private.pem -outform PEM -pubout -out public.pem推荐通过 template 文件过滤器 将密钥从配置文件外部引入,例如假设私钥位于/config/secrets/oidc/jwks/rsa.2048.key:
identity_providers: oidc: jwks: - key: {{ secret "/config/secrets/oidc/jwks/rsa.2048.key" | mindent 10 "|" | msquote }}certificate_chain
可选。用于与key搭配的证书链/捆绑包(DER base64 编码的 PEM 格式)。配置后会在 JSON Web Key Set 的发现端点中启用 x5c 与 x5t(符合 RFC7517)。绝大多数客户端并不校验 JWKS 文档中的这些值,因此很少需要配置。证书链必须:
- 包含与
key匹配的公钥数据; - 所有证书在当前日期均有效;
- 仅包含普遍有效的证书;
- 按顺序签发:第一张证书由第二张签发,第二张由第三张签发,以此类推。
安全相关选项
enable_client_debug_messages
布尔值,默认false。开启后允许向客户端发送额外的调试信息。
minimum_parameter_entropy
整数,默认8。控制授权请求中nonce与state参数的最小长度;设为-1则完全禁用该校验。安全警告:官方不鼓励修改此值——降低它会从理论上削弱某些场景的安全性。如果你的 Relying Party 不发送这些参数或长度不足,应当推动应用修复,而不是调整此值。validator 的实现细节见 identity_providers.go:-1会触发不安全警告,<= 0回退到库默认值oauthelia2.MinParameterEntropy,小于默认值则推送警告。
enforce_pkce
字符串,默认public_clients_only,可选never、public_clients_only、always。PKCE(Proof Key for Code Exchange,[RFC7636])强制执行策略:
public_clients_only(默认):使用 Authorization Code Flow 的公开客户端(如移动应用、SPA)必须使用 PKCE;always:所有使用授权码流程的客户端都必须使用 PKCE;never:不强制。安全警告:改为never可能让客户端应用暴露于 CSRF 与授权码拦截攻击之下。
从源码看,该值在 config.go 中被映射为ProofKeyCodeExchangeConfig:Enforce(对应always)与EnforcePublicClients(对应非never)分别驱动GetEnforcePKCE与GetEnforcePKCEForPublicClients两个接口方法(config.go)。
enable_pkce_plain_challenge
布尔值,默认false。设为true时允许 PKCEplain挑战方法。安全警告:不推荐开启,应用应使用S256挑战方法。开启后,发现端点文档中的code_challenge_methods_supported会追加plain(见 discovery.go)。
enable_jwt_access_token_stateless_introspection
布尔值,默认false。允许以无状态模型对 JWT Access Token 进行 introspection:即 JWT 声明中已包含全部 introspection 所需信息,并假定其未被吊销。除非有非常特殊的需求,强烈不建议开启。启用前提:必须至少有一个客户端配置了access_token_signed_response_alg或access_token_signed_response_key_id(否则该选项不会生效)。
discovery_signed_response_alg 与 discovery_signed_response_key_id
这两个选项用于对 OAuth 2.0 Authorization Server Metadata 与 OpenID Connect Discovery 1.0 响应进行签名,签名后的 JWT 按规范以紧凑编码存放在signed_metadata字段中。默认discovery_signed_response_alg: none(即不包含signed_metadata)。注意事项:
- 多数客户端不支持该特性,且有性能开销,除非有明确需求否则建议保持默认;
- 除
none外,所选算法必须在jwks中配置了对应密钥才算有效; discovery_signed_response_key_id一旦定义,会自动覆盖discovery_signed_response_alg(以指定密钥的算法为准),此时discovery_signed_response_alg被完全忽略;- 该值必须取自
jwks中提供或计算出的 key id。validator 的处理逻辑见 identity_providers.go。
require_pushed_authorization_requests
布尔值,默认false。开启后,所有授权请求都必须走 Pushed Authorization Requests([RFC9126],PAR)流程。该开关会同步反映到发现文档的require_pushed_authorization_requests元数据中(见 discovery.go)。
authorization_policies:基于客户端/用户/网络的授权定制
authorization_policies(字典)允许为不同客户端创建自定义授权策略,常用于基于角色的访问控制(RBAC):例如只允许特定用户访问特定客户端。
重要区分:这里与 Access Control Rules 是完全不同的机制——用途、可用选项都刻意不同(原因详见 OpenID Connect FAQ 与 ADR1)。本节的策略仅适用于授权请求(Authorization Request),不应作为应用自身缺乏基础访问控制的"拐杖"。官方一般建议由 Relying Party 基于可用 claims 自行提供 RBAC。
策略可执行的生效策略(effective policy)有三种:one_factor、two_factor(与标准策略一致),以及仅在策略配置中可用的deny。规则按顺序匹配,第一个完全匹配的规则生效;若命中deny规则,用户不会被询问授权同意,而是直接返回 OpenID Connect 的access_denied错误。
策略的名称(字典键)用于客户端配置的authorization_policy选项。以下示例定义名为policy_name的策略:对services组用户且来自指定网络段时deny,其余人默认two_factor,并应用到client_with_policy_name客户端:
identity_providers: oidc: authorization_policies: policy_name: default_policy: 'two_factor' rules: - policy: 'deny' subject: 'group:services' networks: - '192.168.1.0/24' - '192.168.2.51' clients: - client_id: 'client_with_policy_name' authorization_policy: 'policy_name'校验逻辑(见 identity_providers.go)要点:
- 策略名不能为空,也不能与内置策略名
one_factor、two_factor、deny冲突; rules必须存在,否则策略无效;- 每条规则必须配置
subject或networks至少其一,否则报错。
default_policy
字符串,默认two_factor。当没有任何规则能确定生效策略时使用的默认策略。合法值为one_factor、two_factor、deny。
rules
列表,必填。策略匹配时考虑的规则集合。
policy
字符串,默认two_factor。该规则命中时应用的策略,合法值为one_factor、two_factor、deny。
subject
list(list(string)),与networks二选一(必填其一)。主题匹配条件,语法与 Access Control 的 subject 一致,例如group:services、user:john等。
networks
list(string)(network 语法),与subject二选一(必填其一)。规则适用的网络列表,可使用具名 Network Definitions。
安全说明:
networks规则只适用于资源所有者正在提供授权同意时的授权码流程。对subject条件影响不大,但用户的 IP 地址可能在同意授权后发生变化,且令牌签发后技术上无法再强制执行该检查。详见 ADR1。
lifespans:令牌生命周期
令牌生命周期配置,官方建议尽量贴近默认值,并善用 refresh token(关于长生命周期的风险可参考 token lifespan 讨论)。全局默认值如下(定义在 identity_providers.go):
| 选项 | 默认值 | 说明 |
|---|---|---|
access_token | 1 小时 | Access Token 默认最大生命周期 |
refresh_token | 1 小时 30 分钟 | Refresh Token 默认最大生命周期,可用于换取新的 refresh/access/id token |
id_token | 1 小时 | ID Token 默认最大生命周期 |
authorize_code | 1 分钟 | 授权码默认最大生命周期 |
device_code | 10 分钟 | Device Code 默认最大生命周期 |
关于 refresh token 的一个实用建议:一个好的起点是"比 access token 与 id token 中较高者多 50% 或 30 分钟(取较小者)"。例如默认情况下两者都是 60 分钟,因此 refresh token 默认是 90 分钟。
custom:按客户端定制的生命周期
custom(字典)允许为单个客户端定制生命周期,配合客户端的 lifespan 选项使用。定制粒度非常细:可以只按令牌类型,也可以按"令牌类型 × 授权类型"分别配置。省略的值会自动回退到优先级树的下一级:
- 按令牌类型 × 授权类型定制(grant 级别);
- 按令牌类型定制;
- 全局默认值。
自定义生命周期的名称(字典键)用于客户端lifespan选项。以下是全部可用选项的穷举示例(各选项规则与对应全局选项完全一致,全局项仅为参考):
identity_providers: oidc: lifespans: access_token: '1h' refresh_token: '90m' id_token: '1h' authorize_code: '1m' device_code: '10m' custom: lifespan_name: access_token: '1h' refresh_token: '90m' id_token: '1h' authorize_code: '1m' device_code: '10m' grants: authorize_code: access_token: '1h' refresh_token: '90m' id_token: '1h' device_code: access_token: '1h' refresh_token: '90m' id_token: '1h' implicit: access_token: '1h' refresh_token: '90m' id_token: '1h' client_credentials: access_token: '1h' refresh_token: '90m' id_token: '1h' refresh_token: access_token: '1h' refresh_token: '90m' id_token: '1h' jwt_bearer: access_token: '1h' refresh_token: '90m' id_token: '1h'从 schema 可见,支持的 grant 类型包括authorize_code、device_code、implicit、client_credentials、refresh_token、jwt_bearer,且还额外支持jwt_secured_authorization(JARM,默认 5 分钟)这一全局级选项。
claims_policies:声明(Claim)定制策略
claims_policies(字典)允许定制某个客户端的 claim 行为与可用 claim。字典键为任意名称,客户端通过 claims_policy 引用。
id_token
list(string)。在标准 ID Token claims 之外,将指定的 claims 自动拷贝到 ID Token(前提是相关 scope 已被授予)。
安全警告:这是一个不应常规使用的逃生舱(escape hatch)。它允许将机密的个人身份信息注入通常不加密的 ID Token 中;该行为只对"并不真正支持 OpenID Connect 1.0"的客户端才有必要,往往表明客户端存在明显 bug——尤其是那些不通过
iss、sub而用其他 claims 关联用户的客户端,这属于相当严重的安全问题。官方强烈不建议使用此选项,仅在尽力而为的基础上提供。
id_token_audience_mode
字符串,默认specification。客户端 ID Token audience 的推导模式。官方建议不要配置——默认模式在几乎所有场景下都是正确的;修改前务必阅读集成文档的 audiences 章节,否则可能给信任 Authelia 的 Relying Party 带来意外安全问题。支持的模式:
| 值 | 描述 |
|---|---|
specification | 符合规范的模式,claim 中仅记录 client id |
experimental-merged | 包含specification的全部内容,并额外合并来自 Access Token 的已授予 audience |
任何带
experimental-前缀的模式都可能被无通知地移除或改名;若你在使用这些模式,建议在项目 Discussion 中展示用法以便评估价值。
access_token
list(string)。在标准 JWT Profile claims 之外,将指定 claims 自动拷贝到 Access Token(前提是相关 scope 已被授予)。
custom_claims
字典。该策略中除标准 claims 外可用的自定义 claims 集合。这些 claims 锚定到用户属性上,属性可以来自第一因素后端 的具体属性,也可以是 definitions 中定义的属性。字典键默认为 claim 名与属性名。
- name:该 claim 的名称,默认与字典键相同;
- attribute:该 claim 返回的用户属性名,默认与字典键相同。
validator 会逐一校验:自定义 claim 名不能与标准 claim 冲突、name不能重复映射、attribute必须是已知的用户属性(isUserAttributeValid会检查 LDAP 属性映射、内置标准属性与 File 后端的额外属性,见 identity_providers.go)。
scopes:自定义 Scope
scopes(字典)允许在标准 scope 之外定义自定义 scope。字典键即 scope 名称。
claims
list(string)。该 scope 可用的 claims 集合。注意:
- scope 中的每个 claim 必须是标准 claim,或者能被客户端关联的
claims_policy满足; - validator 会拒绝与标准 scope 重名(
openid、profile、email等)以及所有authelia.前缀的保留 scope(见 identity_providers.go)。
cors:跨域资源共享
部分 OpenID Connect 端点需要允许跨域请求,有些则是可选的。本节用于配置可选部分——当请求携带Origin头时,Authelia 会回复 CORS 响应头。
endpoints
list(string)。启用 CORS 头的端点列表,建议至少包含userinfo。可选项:
authorizationpushed-authorization-requesttokenrevocationintrospectionuserinfo
(schema 中还额外支持device-authorization,见 identity_providers.go。)
allowed_origins
list(string)。允许的来源列表。规则:
- 未配置此项且未启用
allowed_origins_from_client_redirect_uris时,任何 https origin 都被允许;这意味着若想允许 http 端点发起跨域请求,必须手动配置此选项(但不推荐); - origin 只能包含 scheme、主机名与端口,不能有尾斜杠或路径(validator 会拒绝带 path 或 query string 的 origin,见 identity_providers.go);
- 支持通配符 origin
*,但它必须单独出现,且不能与allowed_origins_from_client_redirect_uris同时启用:
identity_providers: oidc: cors: allowed_origins: "*"identity_providers: oidc: cors: allowed_origins: - "*"allowed_origins_from_client_redirect_uris
布尔值,默认false。开启后,自动将所有客户端 redirect URI 的 origin 部分加入allowed_origins,前提是该 URI 使用 http 或 https scheme 且主机名不是localhost。validator 的具体实现见 identity_providers.go。
与客户端配置的衔接
clients(列表,必填)是 provider 配置中另一个必填部分,负责注册具体应用。validator 要求至少配置一个客户端,否则启动校验失败。客户端的authorization_policy、lifespan、claims_policy、scopes等选项分别引用上文定义的策略与生命周期,完整说明见 OpenID Connect 1.0 Registered Clients。
集成验证与后续步骤
完成 provider 配置后,应用(Relying Party)通过以下方式与 Authelia 对接:
- 通过 Well Known 发现端点(OAuth 2.0 Authorization Server Metadata 与 OpenID Connect Discovery 1.0)自动获取各端点地址与能力声明;
- 从发现文档中可见:Authelia 支持
public与pairwise两种 subject 类型、授权码/隐式/混合等多种 response type、form_post/query/fragment/JWT 系列 response mode,以及 client_secret_basic、client_secret_post、client_secret_jwt、private_key_jwt、none 等客户端认证方法(见 discovery.go); - 按 集成指南 中的步骤在具体应用中完成对接与端到端验证。
至此,你已经掌握了 Authelia OpenID Connect 1.0 Provider 的完整配置面:从签名密钥的生成与 JWKS 约束,到 PKCE/PAR 等现代安全机制,再到授权策略、令牌生命周期、claims/scopes 定制与 CORS 调优。每个配置项都有明确的默认值与安全边界,配合源码中的校验逻辑,足以支撑你在生产环境中安全、合规地落地这套 SSO 能力。
【免费下载链接】autheliaThe Single Sign-On Multi-Factor portal for web apps. OpenID Certified™ and Post-Quantum Cryptography Ready.项目地址: https://gitcode.com/GitHub_Trending/au/authelia
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考