Skip to content

协议端点 ​

本页列出 wicket v0.1.4 真正会处理的 HTTP 端点,以及它们接受的方法、认证方式和出错时的响应形态。所有行为都以源码(di/dsl_core.go、handlers/)和对快速开始示例的实测为准。

路由规则 ​

wicket 以中间件形式挂在宿主 handler 前面:

go
handler := hosting.ScopeMiddleware(root)(srv.UseWicket()(app))

每个请求进入时,路由器把 r.URL.Path 与已注册端点的路径做整串、忽略大小写的比较:

  • 命中 → 由对应 handler 处理,宿主的 app 不会被调用;
  • 未命中 → 原样交给宿主的 app。

必须套上 ScopeMiddleware

UseWicket() 依赖 hosting.ScopeMiddleware(root) 放进请求上下文的作用域。少了这一层,wicket 中间件会直接把所有请求放行给宿主,不报错——表现为端点全部变成宿主的 404 或首页。

handler 内部出现无法映射为协议错误的故障(例如存储报错)时,中间件以 HTTP 501 加纯文本错误消息响应(hosting/middleware.go)。生产环境建议在宿主外层再包一层恢复与日志中间件,并留意这段错误文本可能包含内部细节。

已注册端点 ​

下表与 di/dsl_core.go 中的 11 个 hosting.Endpoint 注册一一对应。

路径方法用途要点
/connect/authorizeGET;POST(表单)授权请求入口POST 必须是 application/x-www-form-urlencoded,否则 415。参数错误时 302 到宿主错误页(默认 /home/error?errorId=...)
/connect/authorize/callbackGET用户在登录/同意页完成交互后回到这里,恢复原授权请求非 GET 返回 405
/connect/tokenPOST(表单)令牌端点见下文「授权类型」「客户端认证」。v0.1.4 不校验方法:GET/PUT 也会进入处理逻辑,实测返回 400 invalid_request
/.well-known/openid-configurationGET发现文档非 GET 返回 405;Endpoints.EnableDiscoveryEndpoint=false 时 404。详见发现文档
/.well-known/openid-configuration/jwksGET公钥集 JWKS非 GET 返回 405;EnableDiscoveryEndpoint 或 Discovery.ShowKeySet 为 false 时 404
/connect/userinfoGET、POST用户信息需 Bearer 访问令牌;无令牌或令牌无效 401,令牌缺少 openid 范围 403
/connect/introspectPOST(表单)令牌内省(RFC 7662)调用方以 API 资源名称 + API secret 认证,失败一律 401 且无响应体;非表单 415;非 POST 405
/connect/endsessionGET;POST(表单)RP 发起的登出非表单 POST 415,其余方法 405
/connect/endsession/callbackGET登出完成后渲染前端通道登出页非 GET 405
/connect/checksessionGETOIDC 会话管理的 check-session iframe返回带 CSP 头的 HTML
/connect/cibaPOST(表单)CIBA 后端通道认证请求成功返回 auth_req_id、expires_in(及可选 interval)

部分端点受 WicketOptions.Endpoints 开关控制(关闭后返回 404):userinfo、endsession、endsession/callback、checksession、discovery、jwks。authorize、token、introspect、ciba 四个 handler 不读取这些开关——把 EnableTokenEndpoint 等设为 false 只会让它们从发现文档中消失,请求依然会被处理。

发现文档里出现、但未注册的 URL ​

constants.go 还定义了以下路径常量,发现文档也会默认公布其中几个 URL,但 v0.1.4 没有为它们注册 handler:

路径发现文档字段实际行为
/connect/revocationrevocation_endpoint请求落到宿主 handler,wicket 不处理
/connect/deviceauthorizationdevice_authorization_endpoint同上
/connect/mtls/token、/connect/mtls/revocation、/connect/mtls/introspect、/connect/mtls/deviceauthorizationmtls_endpoint_aliases(仅 MutualTls.Enabled=true 时出现)同上

实测(快速开始示例,宿主首页返回 host app):

text
POST /connect/revocation          → 200 host app
POST /connect/deviceauthorization → 200 host app
POST /connect/mtls/token          → 200 host app

关掉不存在的端点的公告

令牌吊销与设备授权请求在 v0.1.4 不会被 wicket 处理。若你的宿主对未知路径返回 200,客户端甚至会误以为吊销成功。建议在装配时关闭这两项公告:

go
opts.Endpoints.EnableTokenRevocationEndpoint = false
opts.Endpoints.EnableDeviceAuthorizationEndpoint = false

注意第二项同时会把 urn:ietf:params:oauth:grant-type:device_code 从 grant_types_supported 中移除,但不会禁用令牌端点对该授权类型的处理。设备流的现状见设备授权。

支持的授权类型 ​

令牌端点按 grant_type 分派(validators/impl/token_request_validator.go):

grant_type默认可用说明
authorization_code是授权码 + PKCE;plain 方法仅在客户端 AllowPlainTextPkce=true 时接受(默认 false),应坚持 S256
client_credentials是机器对机器
refresh_token是用刷新令牌续期(v0.1.4 不轮换,见 刷新令牌);并发刷新冲突时返回 invalid_grant
urn:ietf:params:oauth:grant-type:device_code是(令牌端点侧)v0.1.4 没有内置设备授权端点,设备码须由宿主自行签发
urn:openid:params:grant-type:ciba是配合 /connect/ciba
password否默认验证器 NotSupportedResourceOwnerPasswordValidator 一律拒绝;需 cfg.SetResourceOwnerValidator(...) 注入实现
其他值否进入扩展授权分支;v0.1.4 的 ServerConfig 未提供注册扩展授权验证器的方法,实测返回 unsupported_grant_type

无论哪种授权类型,客户端还必须在 AllowedGrantTypes 中声明它,否则返回 unauthorized_client。发现文档里的 implicit 指授权端点上的 response_type=token 等流程,不是令牌端点的 grant_type。

客户端认证方式 ​

容器只注册了两个 secret 解析器(di/dsl_core.go)和一个 secret 验证器:

发现文档名解析器读取位置
client_secret_basicBasicAuthenticationSecretParserAuthorization: Basic base64(client_id:client_secret)
client_secret_postPostBodySecretParser表单字段 client_id / client_secret,要求 Content-Type: application/x-www-form-urlencoded

两者解析出的共享密钥都交给 HashedSharedSecretValidator 比对:客户端注册时 Secret.Value 存的是哈希值(示例里用 utils.Sha256("change-me")),请求里带明文。

只带 client_id、不带 secret 的请求被解析为 NoSecret,仅适用于 RequireClientSecret=false 的公共客户端。

v0.1.4 没有 private_key_jwt、client_secret_jwt 或 mTLS 客户端认证的解析器。MutualTls.Enabled=true 只会让发现文档多出 tls_client_auth 等条目,并不会真正启用证书认证——不要打开它。

成功响应 ​

令牌端点成功时返回 application/json,并带 Cache-Control: no-store 与 Pragma: no-cache:

json
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "expires_in": 3600,
  "id_token": "",
  "refresh_token": "",
  "scope": "orders.read",
  "token_type": "Bearer"
}

id_token 和 refresh_token 两个键总是存在,未签发时值为空字符串(而不是省略该字段)。客户端库若以“字段是否存在”判断有无刷新令牌,需要改为判断非空。

错误响应 ​

令牌端点 ​

实测形态(客户端密钥错误):

text
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8

{"custom":{},"error":"invalid_client","error_description":""}

需要注意的几点,均为 v0.1.4 的现状:

  • 除标准的 error、error_description 外,总会附带一个 custom 对象(来自验证器的自定义响应字段,通常为空 {})。
  • error_description 通常是空字符串而不是省略。
  • 所有令牌错误都是 400,包括 invalid_client(RFC 6749 建议 Basic 认证失败用 401)。
  • 响应头里没有 Content-Type: application/json 和 Cache-Control: no-store:错误结果在写入状态码之后才设置头部,这些头被丢弃,Content-Type 由 Go 标准库嗅探为 text/plain。客户端请按状态码 + 解析 body 处理,不要依赖 Content-Type。

其他端点 ​

场景响应
CIBA、内省请求参数错误400,body 为 {"error":...,"error_description":...},没有 custom 字段
userinfo 令牌无效 / 范围不足401 / 403,空 body。源码本意要写 WWW-Authenticate 头,但同样因为头部设置晚于状态码,实测响应中不出现该头
内省调用方认证失败401,空 body
方法不允许 / 媒体类型不支持 / 端点关闭405 / 415 / 404,空 body
authorize 参数错误302 到宿主错误页,错误详情经 errorId 传递

相关阅读 ​

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