第三方 OAuth 接入权限与安全
认证强度与提权
用 acr_values 与 max_age 要求用户完成更强的认证。
有些操作只靠「用户登录过」是不够的——删除数据、变更安全设置、查看敏感信息,都需要确认「此刻是本人」。MuoCeon 用 ACR(Authentication Context Class Reference)表达认证强度,允许你在授权请求里要求最低等级。
两个强度等级
| 等级 | URN | 含义 | 典型达成方式 |
|---|---|---|---|
| AAL1 | urn:muoceon:acr:aal1 | 基础认证 | 密码、恢复码等知识因子 |
| AAL2 | urn:muoceon:acr:aal2 | 持有因子认证 | passkey、设备上的 authenticator |
判定是「达到或超过」,不是精确相等:用户用 passkey 登录后,请求 aal1 同样满足。
怎么要求更高强度
在授权请求里加两个参数:
&acr_values=urn:muoceon:acr:aal2
&max_age=300acr_values是有序偏好列表(空格分隔),服务端取它能满足的最高一档。只写你不接受更低强度的那一档即可。max_age是允许的最大认证年龄(秒)。max_age=300表示「认证必须发生在 5 分钟内」;max_age=0表示要求用户当场重新认证,除非确有需要,否则不要用。
强度不足时会发生什么
这是整个流程里对第三方最透明的一环:
- 用户当前认证强度不够,或认证年龄超限;
- 同意页收到
401 INSUFFICIENT_USER_AUTHENTICATION,且同意票据不会被消费; - 用户被带到提权页,完成更强的认证(例如插入 passkey);
- 完成后带着原请求参数回到同意页,重新走一遍确认;
- 你最终收到的回调与普通流程完全一样,只是时间晚了几十秒。
不要自己实现提权
提权页、票据、断言都是 MuoCeon 内部的机制。你只需要在授权请求里声明要求, 剩下的重试由同意页负责。如果你在回调里做「等一会儿再重试授权」之类的补偿, 反而会把已经成功的授权重复提交。
令牌里的 acr 与 auth_time
令牌会带上本次认证的事实,你可以据此做二次判断:
{
"acr": "urn:muoceon:acr:aal2",
"auth_time": 1760000000
}acr:本次认证实际达到的等级。auth_time:认证发生的时间戳(秒)。
建议在服务端对高敏感接口做一次显式检查:acr 达到要求,且 auth_time 足够新。令牌本身有寿命,但「令牌有效」不等于「刚认证过」。
什么时候该要求 AAL2
| 场景 | 建议 |
|---|---|
| 只读展示用户名、邮箱 | 不要求,AAL1 足够 |
| 修改账号安全设置、删除数据 | 要求 aal2 + 较小的 max_age |
长期离线访问(offline_access) | 首次授权要求 aal2,后续用刷新令牌 |
| 后台批处理 | 不要用交互式流程,考虑 machine 客户端 |
要求过高会显著降低授权率
用户没有 passkey 时,acr_values=aal2 会把他卡在提权页。除非业务确实需要,
否则不要对普通登录也要求 AAL2。