You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编程测试Azure AD B2C用户工作流并获取有效令牌?

解决方案:Azure AD B2C 用户名密码式获取令牌并调用Graph API

针对你需要自动化测试授权工作流、用用户名密码编程获取令牌并查询Graph API组成员的需求,这里有几个可行的方案,尤其适合Ruby和Go这类没有官方ADAL库的后端:

1. 使用ROPC(Resource Owner Password Credentials)流直接获取令牌

Azure AD B2C支持ROPC流,这是专门为**信任的客户端(比如你的自动化测试脚本)**设计的,允许直接用用户名和密码换取令牌,不需要跳转登录页面。

前提准备

  • 在Azure AD B2C中创建一个ROPC类型的用户流(或者用自定义策略,用户流更适合快速上手):
    • 进入B2C租户 -> 用户流 -> 新建用户流 -> 选择“资源所有者密码凭据”类型,配置所需的属性和令牌内容。
  • 确保你的测试账号是本地账号(ROPC不支持社交登录账号,也不支持启用MFA的账号,测试环境建议用无MFA的本地测试用户)。
  • 给你的后端应用注册添加API权限:如果要调用Graph API,需要添加Directory.Read.All或User.Read.All等权限,并且授予管理员同意(因为要查询组成员,需要应用级权限)。

令牌请求示例(HTTP POST)

直接向B2C的令牌端点发送请求:

POST https://{your-b2c-tenant-name}.b2clogin.com/{your-b2c-tenant-name}.onmicrosoft.com/{your-ropc-user-flow-name}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

grant_type=password
&client_id={your-app-client-id}
&scope=https://graph.microsoft.com/.default openid offline_access
&username={test-user-username}
&password={test-user-password}
&response_type=token id_token
  • scope里的https://graph.microsoft.com/.default表示请求应用已配置的所有Graph API权限,这样拿到的令牌就能直接调用Graph API。
  • 成功响应会返回access_token、id_token和refresh_token。

2. 用拿到的令牌调用Graph API查询组成员

拿到access_token后,就可以调用Microsoft Graph API的memberOf端点获取用户所属的组:

GET https://graph.microsoft.com/v1.0/me/memberOf
Authorization: Bearer {your-access-token}

响应会返回用户所在的所有组信息,包括组ID、名称等,满足你验证授权工作流的需求。

3. Ruby和Go的代码实现示例

Ruby 示例(用HTTParty)

require 'httparty'

# 配置参数
tenant_name = "your-b2c-tenant-name"
user_flow = "your-ropc-user-flow-name"
client_id = "your-app-client-id"
username = "test-user@your-tenant.onmicrosoft.com"
password = "test-user-password"

# 获取令牌
token_url = "https://#{tenant_name}.b2clogin.com/#{tenant_name}.onmicrosoft.com/#{user_flow}/oauth2/v2.0/token"
token_response = HTTParty.post(token_url,
  body: {
    grant_type: "password",
    client_id: client_id,
    scope: "https://graph.microsoft.com/.default openid offline_access",
    username: username,
    password: password
  },
  headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
)

access_token = token_response.parsed_response["access_token"]

# 调用Graph API查询组成员
graph_url = "https://graph.microsoft.com/v1.0/me/memberOf"
graph_response = HTTParty.get(graph_url,
  headers: { 'Authorization' => "Bearer #{access_token}" }
)

puts graph_response.parsed_response

Go 示例

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
)

func main() {
	// 配置参数
	tenantName := "your-b2c-tenant-name"
	userFlow := "your-ropc-user-flow-name"
	clientID := "your-app-client-id"
	username := "test-user@your-tenant.onmicrosoft.com"
	password := "test-user-password"

	// 构造令牌请求
	tokenURL := fmt.Sprintf("https://%s.b2clogin.com/%s.onmicrosoft.com/%s/oauth2/v2.0/token", tenantName, tenantName, userFlow)
	data := url.Values{}
	data.Set("grant_type", "password")
	data.Set("client_id", clientID)
	data.Set("scope", "https://graph.microsoft.com/.default openid offline_access")
	data.Set("username", username)
	data.Set("password", password)

	tokenResp, err := http.Post(tokenURL, "application/x-www-form-urlencoded", bytes.NewBufferString(data.Encode()))
	if err != nil {
		fmt.Println("获取令牌失败:", err)
		return
	}
	defer tokenResp.Body.Close()

	var tokenResult map[string]interface{}
	json.NewDecoder(tokenResp.Body).Decode(&tokenResult)
	accessToken := tokenResult["access_token"].(string)

	// 调用Graph API查询组成员
	graphURL := "https://graph.microsoft.com/v1.0/me/memberOf"
	req, _ := http.NewRequest("GET", graphURL, nil)
	req.Header.Set("Authorization", "Bearer "+accessToken)

	graphResp, err := http.DefaultClient.Do(req)
	if err != nil {
		fmt.Println("调用Graph API失败:", err)
		return
	}
	defer graphResp.Body.Close()

	var graphResult map[string]interface{}
	json.NewDecoder(graphResp.Body).Decode(&graphResult)
	fmt.Println("用户所属组:", graphResult)
}

注意事项

  • ROPC流仅适合测试环境,生产环境不建议使用,因为它会直接处理用户密码,存在安全风险。
  • 不支持启用MFA的用户,测试账号请关闭MFA。
  • 确保应用的权限是最小必要的,不要给超过测试所需的权限。

内容的提问来源于stack exchange,提问作者Max Burke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:14:16