如何从OMS工作区获取数据?新文档API认证报错求助
嘿,我来帮你拆解这两个问题——要不要切换到新文档的API方法,还有新代码里的认证错误,咱们一步步来:
一、是否需要遵循新文档的API方法?
你之前用的是旧版Azure Management API(带api-version=2015-11-01-preview),而新文档里的是Log Analytics REST API(api.loganalytics.io),这是微软推出的更现代化、功能更完善的专用接口。
从长远维护和功能扩展来看,建议你逐步迁移到新API:
- 旧版Management API针对OMS的部分功能大概率会被微软逐步弃用(虽然目前还能正常运行),新API会持续迭代新特性;
- 新API的调用逻辑更简洁,支持更灵活的查询语法和批量操作;
- 认证方式除了API密钥,还支持更安全的Azure AD身份验证,适合生产环境的权限管控。
如果你的旧代码已经完全满足当前业务需求,且短期内没有功能升级计划,也可以暂时继续使用,但最好把迁移新API纳入后续规划。
二、新代码的API密钥无效错误解决
你遇到的报错很明确:
{u'error': {u'innererror': {u'message': u'The given API Key is not valid for the request', u'code': u'UnsupportedKeyError'}, u'message': u'Valid authentication was not provided', u'code': u'AuthorizationRequiredError'}}
核心问题是API密钥的来源或使用方式不对,我给你一步步排查修正:
1. 确认API密钥的正确获取路径
新的Log Analytics API使用的密钥不是旧代码里的服务主体application_key,而是来自Log Analytics工作区本身:
- 登录Azure门户,找到你的Log Analytics工作区;
- 进入左侧菜单的设置 -> 代理和API;
- 在“API密钥”区域,复制主密钥或辅助密钥,这才是新API需要的
X-Api-Key值。
2. 确认Workspace ID的正确性
替换代码里的{workspace_id}时,要使用工作区的唯一ID:
- 在工作区的概述页面,找到“工作区ID”(是一个类似
xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx的GUID字符串),直接复制替换占位符。
3. 补全必填的请求参数
新API的POST请求需要在请求体中包含查询语句,你的当前代码里search_param是空的,这也可能导致请求异常。修正后的请求体应该包含query字段,比如:
search_param = { "query": "Type=*", "timespan": "PT24H" # 可选,指定查询时间范围,比如过去24小时 }
4. 修正后的完整新代码示例
import requests import json # 替换为你的实际信息 workspace_id = "你的工作区ID" api_key = "你的工作区API密钥" url = f"https://api.loganalytics.io/v1/workspaces/{workspace_id}/query" headers = { "X-Api-Key": api_key, "Content-Type": "application/json" } search_param = { "query": "Type=*", "timespan": "PT24H" # 可选,按需调整时间范围 } res = requests.post(url=url, json=search_param, headers=headers) print(res.status_code) print(json.dumps(res.json(), indent=2))
5. 可选:用Azure AD认证更安全
如果API密钥方式还是有问题,或者你需要更严格的权限控制,推荐使用Azure AD身份验证(逻辑和旧代码类似,但适配新API):
- 先安装
azure-identity库:pip install azure-identity; - 用服务主体获取token,然后用Bearer token认证:
from azure.identity import ClientSecretCredential import requests # 替换为你的服务主体信息 tenant_id = "你的租户ID" client_id = "你的应用ID" client_secret = "你的应用密钥" credential = ClientSecretCredential(tenant_id, client_id, client_secret) token = credential.get_token("https://api.loganalytics.io/.default") headers = { "Authorization": f"Bearer {token.token}", "Content-Type": "application/json" } # 后续请求逻辑和上面一致 search_param = {"query": "Type=*"} res = requests.post(url=url, json=search_param, headers=headers)
内容的提问来源于stack exchange,提问作者Sachin Aryal

