# Implementing Scim Provisioning With Okta

> 使用 SCIM 2.0 协议以 Okta 作为身份提供商实现自动化用户配置和取消配置。

- Skill: `killvxk/implementing-scim-provisioning-with-okta` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add killvxk/implementing-scim-provisioning-with-okta`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/implementing-scim-provisioning-with-okta/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/implementing-scim-provisioning-with-okta

---


# 使用 Okta 实施 SCIM 配置

## 概述

SCIM（System for Cross-domain Identity Management，跨域身份管理系统）是一种开放标准协议（RFC 7644），用于自动化 Okta 等身份提供商与服务提供商之间的用户身份信息交换。本技能涵盖构建符合 SCIM 2.0 的 API 端点，并与 Okta 集成，实现包括用户配置、取消配置、配置文件更新和组管理在内的自动化用户生命周期管理。

## 前提条件

- 具有管理员访问权限的 Okta 租户（开发者或生产环境）
- 具有 REST API 用户管理能力的应用程序
- TLS 加密端点（必须使用 HTTPS）
- Okta API 令牌或 OAuth 2.0 客户端凭据
- Python 3.9+ 并安装 Flask 或 FastAPI

## 核心概念

### SCIM 2.0 协议

SCIM 通过 JSON 定义了表示用户和组的标准 schema，以及 CRUD 操作的 RESTful API：

| 操作 | HTTP 方法 | 端点 | 描述 |
|-----------|-------------|----------|-------------|
| 创建用户 | POST | /scim/v2/Users | 配置新用户账户 |
| 读取用户 | GET | /scim/v2/Users/{id} | 获取用户详情 |
| 更新用户 | PUT/PATCH | /scim/v2/Users/{id} | 修改用户属性 |
| 删除用户 | DELETE | /scim/v2/Users/{id} | 删除用户账户 |
| 列出用户 | GET | /scim/v2/Users | 带过滤条件列出用户 |
| 创建组 | POST | /scim/v2/Groups | 创建组 |
| 管理组 | PATCH | /scim/v2/Groups/{id} | 添加/移除组成员 |

### Okta SCIM 集成架构

```
Okta (IdP) ──SCIM 2.0 over HTTPS──> SCIM 服务器 ──> 应用数据库
     │                                     │
     ├── 用户分配                          ├── 创建/更新用户
     ├── 用户取消分配                      ├── 停用用户
     ├── 配置文件推送                      ├── 同步属性
     └── 组推送                           └── 管理组
```

### 必需的 SCIM 端点

1. **ServiceProviderConfig** (`/scim/v2/ServiceProviderConfig`)：公告 SCIM 功能
2. **ResourceTypes** (`/scim/v2/ResourceTypes`)：描述支持的资源类型
3. **Schemas** (`/scim/v2/Schemas`)：发布 SCIM schema 定义
4. **Users** (`/scim/v2/Users`)：用户生命周期操作
5. **Groups** (`/scim/v2/Groups`)：组管理操作

## 实施步骤

### 第 1 步：构建 SCIM 2.0 API 服务器

创建基于 Flask 的 SCIM 服务器，实现核心端点。服务器必须处理：

- **用户 CRUD**：创建、读取、更新、删除和列出用户
- **过滤**：支持 `userName` 上的 `eq` 过滤条件（Okta 要求）
- **分页**：返回 `startIndex`、`itemsPerPage` 和 `totalResults`
- **认证**：所有端点上的 Bearer Token 验证

```python
from flask import Flask, request, jsonify
import uuid
from datetime import datetime

app = Flask(__name__)

# Okta 认证使用的 Bearer Token
SCIM_BEARER_TOKEN = "your-secure-token-here"

def require_auth(f):
    def wrapper(*args, **kwargs):
        auth = request.headers.get("Authorization", "")
        if not auth.startswith("Bearer ") or auth[7:] != SCIM_BEARER_TOKEN:
            return jsonify({"detail": "Unauthorized"}), 401
        return f(*args, **kwargs)
    wrapper.__name__ = f.__name__
    return wrapper

@app.route("/scim/v2/Users", methods=["POST"])
@require_auth
def create_user():
    data = request.json
    user_id = str(uuid.uuid4())
    user = {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
        "id": user_id,
        "userName": data.get("userName"),
        "name": data.get("name", {}),
        "emails": data.get("emails", []),
        "active": True,
        "meta": {
            "resourceType": "User",
            "created": datetime.utcnow().isoformat() + "Z",
            "lastModified": datetime.utcnow().isoformat() + "Z",
            "location": f"/scim/v2/Users/{user_id}"
        }
    }
    # 将用户持久化到数据库
    return jsonify(user), 201

@app.route("/scim/v2/Users", methods=["GET"])
@require_auth
def list_users():
    filter_param = request.args.get("filter", "")
    start_index = int(request.args.get("startIndex", 1))
    count = int(request.args.get("count", 100))
    # 解析过滤条件: userName eq "john@example.com"
    # 使用过滤条件查询数据库
    return jsonify({
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
        "totalResults": 0,
        "startIndex": start_index,
        "itemsPerPage": count,
        "Resources": []
    })
```

### 第 2 步：配置 Okta 应用程序

1. **创建 SCIM 应用集成**：
   - 导航至"Okta Admin Console > Applications > Create App Integration"
   - 选择 SWA 或 SAML 2.0 作为登录方法
   - 在"General"选项卡中，为 Provisioning 选择 SCIM

2. **配置 SCIM 连接**：
   - SCIM 连接器基础 URL：`https://your-app.com/scim/v2`
   - 唯一标识符字段：`userName`
   - 支持的配置操作：推送新用户、推送配置文件更新、推送组
   - 认证模式：HTTP Header（Bearer Token）

3. **启用配置功能**：
   - 发送至应用：创建用户、更新用户属性、停用用户
   - 配置 Okta 配置文件与 SCIM schema 之间的属性映射

### 第 3 步：映射属性

将 Okta 用户配置文件属性映射到 SCIM schema：

| Okta 属性 | SCIM 属性 | 方向 |
|---------------|----------------|-----------|
| login | userName | Okta -> 应用 |
| firstName | name.givenName | Okta -> 应用 |
| lastName | name.familyName | Okta -> 应用 |
| email | emails[type eq "work"].value | Okta -> 应用 |
| department | urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department | Okta -> 应用 |

### 第 4 步：实现错误处理

SCIM 指定了标准错误响应格式：

```json
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
  "detail": "用户已存在",
  "status": "409",
  "scimType": "uniqueness"
}
```

常见错误代码：400（错误请求）、401（未授权）、404（未找到）、409（冲突）、500（服务器内部错误）。

### 第 5 步：使用 Runscope/Okta SCIM 验证器测试

Okta 提供自动化 SCIM 测试套件（通过 Runscope/BlazeMeter），验证您的 SCIM 实现是否符合所有必需操作：

1. 从 OIN 提交门户导入 Okta SCIM 2.0 测试套件
2. 配置基础 URL 和认证令牌
3. 运行涵盖用户 CRUD、过滤和分页的完整测试套件
4. 在提交到 OIN 之前修复所有失败的测试

## 验证清单

- [ ] SCIM 服务器可通过 HTTPS 访问且拥有有效的 TLS 证书
- [ ] 所有端点强制执行 Bearer Token 认证
- [ ] 用户创建返回 201 及完整用户表示
- [ ] 按 `userName eq "..."` 过滤的用户搜索正常工作
- [ ] 分页参数（`startIndex`、`count`）正确处理
- [ ] 用户停用设置 `active: false`（而非硬删除）
- [ ] PATCH 操作支持 `add`、`replace`、`remove` 操作
- [ ] 组推送正确创建和管理组成员关系
- [ ] Okta SCIM 验证器测试套件通过所有测试
- [ ] 错误响应符合 SCIM 错误 schema

## 参考资料

- [SCIM 2.0 协议 RFC 7644](https://tools.ietf.org/html/rfc7644)
- [Okta SCIM 开发者指南](https://developer.okta.com/docs/guides/scim-provisioning-integration-overview/main/)
- [构建 SCIM API 服务 - Okta](https://developer.okta.com/docs/guides/scim-provisioning-integration-prepare/main/)
- [SCIM 核心 Schema RFC 7643](https://tools.ietf.org/html/rfc7643)

