使用 Fleet 部署 Apple 账户开通(Apple account provisioning):基于 ROPG IdP 的 macOS 本地账户创建与密码同步实战
2026/9/20 23:09:27 网站建设 项目流程

使用 Fleet 部署 Apple 账户开通(Apple account provisioning):基于 ROPG IdP 的 macOS 本地账户创建与密码同步实战

【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet

Fleet 的 Apple 账户开通功能(Apple account provisioning)能够在你通过 Apple Business(自动注册/ADE)为 macOS 主机完成注册时,使用终端用户的身份提供商(IdP)凭据自动创建 macOS 本地账户,并在之后持续保持本地账户密码与 IdP 同步。它借助内置于 Fleet Desktop 应用中的 Fleet Platform SSO 扩展,通过 Fleet 服务器将认证代理给任何支持 OAuth 资源所有者密码授权(Resource Owner Password Grant,ROPG)的 IdP。本文以 Okta 为例,完整演示从 Okta 应用创建、Fleet 集成配置、setup experience 编排到配置描述文件上传的端到端落地流程,并深入到当前开源仓库的源码实现,帮助你理解其认证链路、安全边界与故障排查方式。

该功能需要 Fleet Premium。

如果你的 IdP 本身提供原生 Platform SSO 集成(如 Okta Device Access 或 Microsoft Entra),建议优先使用原生集成。Fleet 的账户开通面向的是原生集成不可用或未授权使用的场景。

你得到什么(以及暂时得不到什么)

启用 Apple 账户开通后:

  • 终端用户在 Setup Assistant 期间使用其 IdP 用户名和密码进行认证,macOS 使用该密码创建本地账户。
  • 本地账户密码与 IdP 保持同步。IdP 中修改密码后,在登录窗口、锁屏或 FileVault 解锁界面使用新密码登录即可更新本地密码,且钥匙串(keychain)保持完好。
  • 本地账户的短名称(short name)和全名(full name)可通过TokenToUserMapping从 IdP 属性映射得到。

目前暂不提供的部分:

  • 对 SaaS 应用和网站的单一登录(SSO)。Fleet 的扩展目前仅处理账户创建与密码同步。

之所以必须使用 OAuth ROPG,是因为密码同步需要 IdP 验证用户的真实密码。其他桌面密码同步产品在开通与同步时也使用同一类流程。由于 ROPG 会将用户名和密码直接发送到令牌端点,因此会绕过 MFA,部分组织的安全策略可能不允许这样做。

前置条件

  • Fleet Premium
  • 运行 macOS 26 或更高版本、通过 Apple Business 走 ADE 注册的 macOS 主机
  • 支持 OAuth ROPG 的 IdP(本指南使用 Okta)
  • 为目标 fleet 配置好的 setup experience
  • 包含 Fleet Platform SSO 扩展的 Fleet Desktop 应用,可作为 Fleet 维护的应用 获取

账户开通目前只能为“所有 fleet(All fleets)”配置,且仅支持单用户 macOS 主机。

第一步:在 Okta 中创建 OAuth ROPG 应用

Okta 仅在 Native 应用集成上支持 Resource Owner Password 授权。

  1. 登录 Okta Admin Console,进入Applications > Applications > Create App Integration
  2. 登录方式选择OIDC - OpenID Connect,应用类型选择Native Application,点击Next
  3. 为应用命名,例如“Fleet account provisioning”。
  4. Grant type下勾选Resource Owner Password
  5. Assignments下,将应用分配给将要注册 Mac 的用户或用户组,然后点击Save
  6. 在应用的General选项卡中,点击Client Credentials区域的Edit,将Client authentication设置为Client secret,点击Save
  7. 复制Client IDClient secret,在第 3 步中将其添加到 Fleet。

接下来,确认应用可以完成仅密码登录:

  1. 进入Applications > Applications,打开你的应用,选择Sign On选项卡。
  2. 确保分配给应用的认证策略允许以Password作为单一因素登录。如果策略要求 MFA,ROPG 请求将会失败。

最后,找到你的令牌 URL。Fleet 推荐使用default授权服务器,因为它支持第 2 步中名称映射所用的自定义声明:

  1. 进入Security > API > Authorization Servers,打开default
  2. 你的令牌 URL 是IssuerURI 加上/v1/token,例如https://example.okta.com/oauth2/default/v1/token
  3. Access Policies选项卡中,确保分配给该应用的策略规则允许Resource Owner Password授权类型。

你也可以使用 Okta 的组织授权服务器(https://example.okta.com/oauth2/v1/token),但它不支持自定义声明,因此使用TokenToUserMapping的短名称映射将不可用。

第二步:映射短名称与全名(可选)

不做任何映射时,macOS 会使用终端用户的 IdP 用户名作为本地账户的账户名(短名称),因此以fleetie@example.com登录的用户会得到fleetie@example.com作为账户名。要想获得类似fleetie这样更友好的账户名,需要在 Okta 中添加一个自定义声明,并在配置描述文件的TokenToUserMapping中映射它。

Fleet 会将来自 IdP ID 令牌的标准emailnamepreferred_username声明,以及名称以account开头的任何自定义声明转发到 Mac。请相应地命名自定义声明,例如accountNameaccountFullName

在 Okta 中添加短名称声明:

  1. 进入Security > API > Authorization Servers,打开default
  2. Claims选项卡中点击Add Claim,然后填写:
    • Name:accountName
    • Include in token type:ID Token, Always
    • Value type:Expression
    • Value:String.substringBefore(user.login, "@")
    • Include in:Any scope
  3. 点击Create

对于全名,当授予profilescope 时(Fleet 默认请求openid profile email),标准name声明开箱即用。如果你希望使用不同的值,也可以按相同方式添加自定义的accountFullName声明。

在第 5 步中,你需要在配置描述文件的TokenToUserMapping字典里引用这些声明名称。

第三步:将 Fleet 连接到 IdP

  1. 在 Fleet 中,进入Settings > Integrations > Account provisioning
  2. 输入第 1 步得到的Token URLClient IDClient secret,然后保存。

也可以使用 GitOps 在default.yml中配置:

controls: apple_account_provisioning: oauth_idp_token_url: https://example.okta.com/oauth2/default/v1/token oauth_idp_client_id: 0oa12345abcdeFGHI678 oauth_idp_client_secret: # TODO: client secret (masked and non-exportable from the API)

从源码结构看,这一 GitOps 片段与 server/fleet/apple_psso.go 中定义的AppleAccountProvisioning结构体字段一一对应:OAuthIdPTokenURL(上游 OIDC 令牌端点)、OAuthIdPClientID(在 IdP 注册的客户端/应用 ID)与OAuthIdPClientSecret。其中oauth_前缀是为将来引入其他认证方式(如 LDAP)预留的命名空间。Configured()方法仅在令牌 URL 与客户端 ID 非空时返回 true——client secret 不参与此检查,因为写入路径保证了只要公开字段被设置,就会有加密存储的 secret 与之配套。

关于凭据安全,apple_psso.go 的注释明确说明:client secret永远不会持久化到 AppConfig JSON 中。写入时它会被剥离出来,加密存储在mdm_config_assets中,API 仅返回掩码后的值;令牌 URL 与客户端 ID 则存储在 JSON 中。

第四步:将 Fleet 的 Platform SSO 应用加入 setup experience

包含 Platform SSO 扩展的 Fleet Desktop 应用默认不会安装。请将其添加为 setup experience 软件,使其在 Setup Assistant 期间、用户到达登录界面之前完成安装:

  1. 在 Fleet 中进入目标 fleet 的Software页面,选择Add software,打开Fleet-maintained选项卡,添加Fleet Desktop
  2. 进入Controls > Setup experience > Install software,勾选 Fleet Desktop 应用,使其在 setup experience 期间安装。
  3. 同时确认Controls > Setup experience > Users中的End user account已选择AdminStandard,以确保在设备上创建本地用户账户。如果选择了None,用户完成注册后会遇到灰色登录界面,其凭据无法生效。

第五步:创建并上传配置描述文件

扩展由单个包含 2 个 payload 的配置描述文件激活:一个Extensible Single Sign-Onpayload 和一个Associated Domainspayload。从仓库中的 示例描述文件 开始,将其中所有fleet.example.com替换为你 Fleet 服务器的域名。

在 Extensible Single Sign-On payload 中:

  • ExtensionIdentifier:com.fleetdm.fleet-desktop.pssoextensionTeamIdentifier:8VBZ3948LU。请原样使用这些值。
  • ExtensionData > BaseURLURLs:你的 Fleet 服务器 URL。
  • RegistrationToken:$FLEET_VAR_PSSO_DEVICE_REGISTRATION_TOKEN。Fleet 会在描述文件投递到每台主机时,用每个设备唯一的注册令牌替换此变量。
  • EnableRegistrationDuringSetupUseSharedDeviceKeys:均为true,使用户在 Setup Assistant 期间完成注册。
  • TokenToUserMapping:将 macOS 账户字段映射到 Mac 收到的令牌中的声明名称。示例描述文件将短名称映射到第 2 步的accountName声明,将全名映射到标准name声明:
<key>TokenToUserMapping</key> <dict> <key>AccountName</key> <string>accountName</string> <key>FullName</key> <string>name</string> </dict>

如果跳过了第 2 步,请删除AccountName键(或整个TokenToUserMapping字典),macOS 将使用 IdP 用户名作为账户名。

$FLEET_VAR_PSSO_DEVICE_REGISTRATION_TOKEN只允许出现在 Fleet SSO 扩展 payload 的RegistrationToken键中。Fleet 在查看已投递的InstallProfile命令时会对该令牌进行脱敏,因此它永远不会暴露在 UI 或 API 中。

在 Associated Domains payload 中,两个应用标识符(8VBZ3948LU.com.fleetdm.fleet-desktop8VBZ3948LU.com.fleetdm.fleet-desktop.pssoextension)都必须列出authsrv:加上你的 Fleet 服务器域名。

将描述文件上传到目标 fleet 的Controls > OS settings > Custom settings

不要使用标签(label)来限定此描述文件的作用范围。带标签的描述文件可能无法在 Setup Assistant 前及时投递,如果发生这种情况,用户将不会被提示登录。

从源码看注册令牌与设备注册机制

注册令牌并非一个简单的占位符,而是由 Fleet 签名、绑定到特定主机的 JWT。server/fleet/apple_psso.go 中的PSSODeviceRegistrationRequest记录了设备注册请求的完整结构:扩展在设备上基于 Secure Enclave 生成签名 + 加密两对密钥对,提交公钥及其 kid(key ID)以及RegistrationToken。在 Password 模式下这是纯密钥注册——用户身份是在每次密码登录的令牌端点上才确立的。

PSSOKey结构体(apple_psso.go)按 kid(密钥字节的 base64 SHA-256)索引已注册设备的公钥,服务器据此在扩展携带带该 kid 的 JWT 时解析出所属设备。一台主机可持有同类型的多个密钥:重新注册会新增密钥而不会使旧密钥失效。从 server/service/integration_mdm_apple_psso_test.go 的端到端测试可见:空令牌、伪造的非 Fleet 签名令牌均会被拒绝注册,成功注册后设备会持有签名与加密两把密钥(require.Len(t, keys, 2))。

密码登录链路与声明转发

集成测试中的pssoMockIdP(integration_mdm_apple_psso_test.go)是 OAuth2 ROPG 令牌端点的替身:Fleet 的 PSSO 登录流程向它 POSTgrant_type=password,并从返回的id_token中读取用户声明。测试验证(L181-L205):设备最终拿到的 ID 令牌由 Fleet 以自己的 JWKS 签发,其中sub为 IdP 主题、email/name/preferred_username被转发,而accountName这类以account前缀命名的自定义声明同样被转发,供描述文件中的TokenToUserMapping映射为 macOS 短名称——这与文档中“名称以account开头的自定义声明会被转发”的说明完全吻合。

测试还覆盖了密码加密传输模式(L207-L220):在EncryptOnWire模式下,普通密码不再出现在断言(assertion)负载中,而是放入加密断言内,grant_type变为urn:ietf:params:oauth:grant-type:jwt-bearer。此外,PSSOClaims结构体(apple_psso.go)中的RefreshTokenExpiresIn字段承载上游 IdP 的 OAuth 令牌响应字段,设备将刷新令牌视为不透明值(用于静默 SSO 续期),ExpiresIn为访问/刷新令牌的生命周期(秒)。

终端用户体验

  1. 用户开启 Mac,设备通过自动注册完成 ADE 注册。终端用户认证是可选的;若已启用,用户先用 IdP 凭据登录。
  2. Setup experience 安装 Fleet Desktop 应用并投递配置描述文件。
  3. 在 Setup Assistant 期间、Fleet 的 setup experience 窗口关闭后,用户被提示使用其 IdP 用户名和密码登录。
  4. macOS 创建本地账户。密码即用户的 IdP 密码,账户名与全名来自已配置的TokenToUserMapping(如果配置了的话)。账户创建界面会显示出来,但此时值被锁定,用户无法编辑。

设置完成后,密码同步按如下方式工作:

  • 用户在 IdP 中修改密码,然后用新密码登录或解锁时,本地密码同步,并出现确认通知。钥匙串保持完好。
  • 修改密码后用户继续使用旧密码,则该密码在 Mac 下一次与 IdP 检入(check in)前(最长 4 小时)仍然可用。之后,macOS 会在下次桌面登录时提示用户同步。
  • FileVault 解锁适用于同步后的密码。
  • 如果 Fleet 服务器不可达,用户永远不会被锁在门外。现有本地密码在连接恢复前一直有效。

建议在通过 IdP 完成密码修改后,指导用户立即用新密码锁定并解锁其 Mac,以便立刻同步 Mac 密码,而不是依赖稍后自动发生。

从源码结构看,密码同步的“检入/离线解锁”机制有专门的支撑实现:PSSOSettings(apple_psso.go)是按请求组装的解析后配置,包括 Fleet 自身的基础 URL(作为令牌签发者并用于构建 AASA/JWKS URL)、上游 IdP 令牌端点、客户端 ID/secret,以及默认的openid profile emailscope 字符串。集成测试中的KeyRequest/KeyExchange用例(L222-L229)验证了离线解锁所需的密钥请求与 ECDH 密钥交换流程——即使 Fleet 服务器暂时不可达,设备仍能利用已下发的密钥完成解锁。

故障排查

用户在 Setup Assistant 期间没有被提示登录。

确认 Fleet Desktop 应用已设置为 setup experience 软件(第 4 步)、描述文件已上传到同一 fleet 且未做标签限定(第 5 步),并且主机运行的是 macOS 26 或更高版本。

使用有效凭据登录失败。

检查 Okta 应用配置(第 1 步)。必须启用Resource Owner Password授权,客户端认证必须设置为Client secret,用户必须已分配给该应用,且应用的认证策略必须允许仅密码登录。同时确认 Fleet 中的令牌 URL 指向正确的授权服务器,且其访问策略允许密码授权。

账户名是完整的电子邮件地址。

accountName声明没有到达 Mac。确认自定义声明存在于与令牌 URL 相同的授权服务器上(自定义声明需要自定义授权服务器,而不是组织授权服务器),确认它包含在 ID 令牌中,并且名称以account开头。

用户被提示输入之前的密码。

有时在用户注销后重新登录(而非锁定/解锁 Mac)时,用户会在桌面被提示输入之前的密码。这是预期行为,用户应输入之前的密码来完成该过程。如果他们无法完成此过程,FileVault 密码可能不会与其新密码同步。

进一步阅读

  • Setup experience
  • Deploying Platform SSO with Okta Device Access
  • 示例 Platform SSO 配置描述文件
  • Apple 账户开通配置的结构体定义与凭据存储说明
  • Apple Platform SSO 端到端集成测试

【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询