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

使用Python或Microsoft Graph API创建AppRoles遇405错误,求正确方法

如何通过Python正确创建Azure AD AppRoles?

我在查找创建/删除AppRoles的相关文档时遇到困难,希望通过Python实现AppRoles的创建,以下是我的代码:

import requests
from msal import ConfidentialClientApplication

# Define the Azure AD credentials and API endpoints
tenant_id = "<your tenant ID>"
client_id = "<your client ID>"
client_secret = "<your client secret>"

authority_url = f'https://login.microsoftonline.com/{tenant_id}'
scope = ['https://graph.microsoft.com/.default']

# api_version = 'beta'
api_version = 'v1.0'

# Define the app role properties
app_role_name = 'APIAppRole'
app_role_description = 'app role for API user'

# Authenticate and get an access token using the MSAL library
app = ConfidentialClientApplication(
    client_id=client_id,
    client_credential=client_secret,
    authority=authority_url
)
token = app.acquire_token_for_client(scopes=scope)

# Create the app role using the Microsoft Graph API
url = f'https://graph.microsoft.com/{api_version}/applications/{client_id}'
headers = {
    'Authorization': f'Bearer {token["access_token"]}',
    'Content-Type': 'application/json'
}
body = {
    'allowedMemberTypes': [
        'User',
        'Group'
    ],
    'displayName': app_role_name,
    'description': app_role_description,
    'id': 'lkjasldkjpq9u934l',
    'isEnabled': True,
    'value': app_role_name
}
response = requests.post(url, headers=headers, json=body)
response.raise_for_status()

执行代码时出现如下错误:

raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 405 Client Error: Method Not Allowed for url: https://graph.microsoft.com/v1.0/applications/656

问题分析与修正方案

核心问题

  1. 请求方法错误:/applications/{object-id}端点不支持POST请求,修改应用属性(包括添加AppRole)需要使用PATCH方法。
  2. ID使用错误:applications端点需要传入应用对象ID(而非客户端IDclient_id),客户端ID是应用的appId属性,需先通过appId查询对应的应用对象ID。
  3. AppRole的ID不合法:id字段必须是唯一的GUID,不能使用自定义字符串,需生成合法的GUID值。
  4. 请求体格式错误:添加AppRole需要在请求体中指定appRoles数组,将新角色对象追加到现有角色列表中(避免覆盖原有角色)。

修正后的完整代码

import requests
import uuid
from msal import ConfidentialClientApplication

# Azure AD credentials
tenant_id = "<your tenant ID>"
client_id = "<your client ID>"
client_secret = "<your client secret>"

authority_url = f'https://login.microsoftonline.com/{tenant_id}'
scope = ['https://graph.microsoft.com/.default']
api_version = 'v1.0'

# App role properties
app_role_name = 'APIAppRole'
app_role_description = 'app role for API user'

# Authenticate to get access token
app = ConfidentialClientApplication(
    client_id=client_id,
    client_credential=client_secret,
    authority=authority_url
)
token_result = app.acquire_token_for_client(scopes=scope)
access_token = token_result.get('access_token')

if not access_token:
    raise Exception(f"Failed to get access token: {token_result.get('error_description')}")

headers = {
    'Authorization': f'Bearer {access_token}',
    'Content-Type': 'application/json'
}

# Step 1: Get application object ID using client_id (appId)
search_url = f'https://graph.microsoft.com/{api_version}/applications?$filter=appId eq \'{client_id}\''
response = requests.get(search_url, headers=headers)
response.raise_for_status()
app_data = response.json()['value'][0]
app_object_id = app_data['id']
existing_app_roles = app_data.get('appRoles', [])

# Step 2: Generate unique GUID for new app role
new_app_role_id = str(uuid.uuid4())

# Step 3: Prepare new app role and update the appRoles array
new_app_role = {
    'allowedMemberTypes': ['User', 'Group'],
    'displayName': app_role_name,
    'description': app_role_description,
    'id': new_app_role_id,
    'isEnabled': True,
    'value': app_role_name,
    'origin': 'Application'  # Required for v1.0 endpoint
}

# Append new role to existing roles (avoid overwriting)
updated_app_roles = existing_app_roles + [new_app_role]

# Step 4: PATCH the application to add the new app role
update_url = f'https://graph.microsoft.com/{api_version}/applications/{app_object_id}'
patch_body = {'appRoles': updated_app_roles}
response = requests.patch(update_url, headers=headers, json=patch_body)
response.raise_for_status()

print(f"App role '{app_role_name}' created successfully!")

关键说明

  • 权限要求:确保服务主体拥有Application.ReadWrite.All或Application.ReadWrite.OwnedBy的应用权限(已授予管理员同意)。
  • 避免覆盖原有角色:代码先获取现有appRoles数组,再追加新角色,不会丢失已存在的AppRole。
  • GUID生成:使用Python内置的uuid模块生成符合要求的唯一ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:54:58