Skip to content

核心概念 ​

本页把 wicket 里反复出现的名词串成一张图:谁签发令牌、给谁签、签什么、凭什么签,以及这些东西在代码里由谁装配。

签发者(issuer) ​

签发者是授权服务器的身份标识,写进每个令牌的 iss 声明,也是发现文档里的 issuer 字段。

  • 设置了 WicketOptions.IssuerUri 时,签发者就是它(去掉末尾 /)。
  • 未设置时,wicket 按当前请求推导:http(s):// + r.Host,其中是否 https 只看 r.TLS 是否非空。

生产环境务必显式设置 IssuerUri,否则同一个服务经不同主机名访问会得到不同的签发者,令牌校验随之失败。

go
opts := godi.GetRequired[*options.WicketOptions](root)
opts.IssuerUri = "https://id.example.com"

客户端(Client) ​

客户端是向 wicket 申请令牌的应用:后端服务、单页应用、移动 App、设备等。由 storage/models.Client 描述,关键字段:

  • ClientId / ClientSecrets:客户端标识与密钥(密钥以 utils.Sha256 哈希后存放)。
  • 允许的授权类型:通过 SetAllowedGrantTypes 设置(字段本身未导出,会校验非法组合)。
  • AllowedScopes:客户端可以申请的作用域。
  • RedirectUris:授权码流回跳地址白名单。

详见 客户端与资源。

资源与作用域 ​

wicket 把“令牌能访问什么”拆成三类模型:

模型作用出现在
IdentityResource(身份资源)一组用户身份声明,如 openid→sub、profile→name 等身份令牌、UserInfo
ApiScope(API 作用域)客户端可申请的一项访问权限,如 orders.read访问令牌的 scope
ApiResource(API 资源)一个受保护的 API,把若干 ApiScope 归组,并持有内省用的 ApiSecrets访问令牌的 aud;内省端点的调用方身份

客户端请求 scope=openid profile orders.read 时,openid、profile 匹配身份资源,orders.read 匹配 API 作用域,其所属的 API 资源名进入访问令牌受众。

令牌 ​

令牌用途形态
访问令牌(access token)调用 APIJWT(头部 typ 为 at+jwt),默认 RS256 签名
引用令牌(reference token)访问令牌的另一种形态不透明句柄,令牌内容存在 ReferenceTokenStore,API 需调用内省端点校验。v0.1.4 尚不签发,见下方说明
身份令牌(id token)向客户端证明“谁登录了”JWT,仅在 OIDC 请求(含 openid 作用域)中签发
刷新令牌(refresh token)换取新的访问令牌不透明句柄,存于 RefreshTokenStore;客户端需 AllowOfflineAccess = true 并申请 offline_access

引用令牌在 v0.1.4 中尚未接通

Client.AccessTokenType 字段可以设为 wicket.AccessTokenTypeReference,但 v0.1.4 的签发路径没有读取它:实测设置后令牌端点仍返回 JWT。ReferenceTokenStore 目前只在令牌校验一侧使用。需要“可即时作废”的访问令牌时,请缩短 AccessTokenLifetime。

授权类型(grant type) ​

授权类型常量典型场景
client_credentialswicket.GrantTypesClientCredentials服务对服务,无用户参与
authorization_codewicket.GrantTypesCode有用户登录的 Web / 移动 / SPA,默认要求 PKCE
refresh_token—用刷新令牌续期。无需列入客户端允许的授权类型;刷新令牌只在客户端 AllowOfflineAccess = true 且请求 offline_access 时签发
CIBA(urn:openid:params:grant-type:ciba)wicket.GrantTypesBackchannelAuthentication后端通道发起、用户在另一设备确认
设备码(urn:ietf:params:oauth:grant-type:device_code)wicket.GrantTypesDeviceFlow令牌端点可处理,但 v0.1.4 没有内置设备授权端点
passwordwicket.GrantTypesPassword默认拒绝;需宿主用 cfg.SetResourceOwnerValidator 注入校验器

各流程的完整步骤见 授权流程。

认证方案 ​

“认证方案”是宿主应用识别浏览器端已登录用户的方式。wicket 预置两个基于 cookie 的方案名:

方案名常量用途
wicketwicket.DefaultCookieAuthenticationScheme用户在宿主登录页完成登录后的主会话 cookie
wicket.externalwicket.ExternalCookieAuthenticationScheme外部登录(Google、Facebook 等)回调期间暂存外部身份

v0.1.4 没有内置 cookie 处理器

这两个方案默认注册的是一个“不支持”的占位 handler:认证永远得到“未登录”,Challenge 直接报错。要跑通需要用户登录的流程(授权码、结束会话等),宿主必须为这两个方案提供自己的 auth.Handler 实现:

go
cfg.SetAuthenticationHandlerProvider(wicket.DefaultCookieAuthenticationScheme,
	func(p godi.Provider) auth.Handler { return newMyCookieHandler(p) }) // newMyCookieHandler 由宿主实现(示意)

client_credentials 等不涉及浏览器用户的流程不受影响。

此外还内置了 Google、Facebook、Bearer(JWT Bearer)几个方案的 handler,见 身份接入。

组合根(di.Root)与 ServerConfig ​

wicket 的全部服务由一个代码生成的依赖注入容器装配,入口是 di.NewRoot():

go
root, err := di.NewRoot()   // 返回 (*di.Root, error)
if err != nil { log.Fatal(err) }
defer root.Close()

opts := godi.GetRequired[*options.WicketOptions](root) // 协议选项
cfg  := root.ServerConfig()                            // 宿主注入点

两个对象分工明确:

  • *options.WicketOptions:协议行为的开关与参数(签发者、端点、交互页 URL、输入长度限制……)。见 配置选项。
  • *di.ServerConfig:宿主向 wicket 注入“外部世界”的地方——客户端与资源列表、签名凭据、各类存储、认证 handler、用户资料服务等。所有注入方法都是 SetXxx(value) 或 SetXxxProvider(func() value) 两种形式。

装配完成后调用 cfg.Freeze():它校验所有存储端口都已注入(或已声明内存回退),否则立即 panic。之后用 server.DefaultServer(root, ...) 构造服务器、用 srv.UseWicket() 得到中间件。详见 嵌入宿主应用。

存储端口三族 ​

wicket 的有状态数据通过三族接口(端口)访问,宿主注入实现:

端口族包存什么注入方法
storagestorage授权码、刷新令牌、引用令牌、用户同意、持久化授权、设备码、CIBA 请求、授权参数消息SetAuthorizationCodeStore、SetRefreshTokenStore 等
sessionsession服务端会话记录SetSessionStore
keymgmtkeymgmt自动管理的签名密钥及其生命周期SetRecordStore

另有两类不属于“持久化”的输入:客户端与资源(SetClients 等,配置数据)、签名凭据与验签密钥(SetSigningCredentialStores / SetValidationKeysStores)。

每族都有对应的契约测试套件(storage/storagetest、session/sessiontest、keymgmt/keymgmttest),适配器通过套件后才算合规。详见 持久化存储 与 存储端口。

相关阅读 ​

以 Apache License 2.0 发布 · 文档内容 © 2026 Wicket 作者