如何使用MSAL Python库获取Azure注册应用的用户角色
使用MSAL Python获取Azure AD应用的用户角色
前提准备
- 确保你的Azure AD应用已配置应用角色,且目标用户已被分配对应角色
- 安装MSAL Python库:
pip install msal
代码实现
场景1:Web应用(机密客户端,授权码流程)
适用于后端服务通过授权码获取用户令牌的场景:
import msal # 替换为你的应用配置 CLIENT_ID = "你的应用客户端ID" TENANT_ID = "你的租户ID" CLIENT_SECRET = "你的应用客户端密码" AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}" SCOPE = ["User.Read", "openid", "profile"] # 必须包含openid以获取id_token REDIRECT_URI = "你的应用重定向URI" # 初始化机密客户端 app = msal.ConfidentialClientApplication( CLIENT_ID, authority=AUTHORITY, client_credential=CLIENT_SECRET ) # 假设你已从前端获取到授权码 authorization_code = "用户授权后返回的授权码" # 获取包含用户信息的令牌 result = app.acquire_token_by_authorization_code( authorization_code, scopes=SCOPE, redirect_uri=REDIRECT_URI ) # 提取用户角色 if "id_token_claims" in result: user_roles = result["id_token_claims"].get("roles", []) print("用户已分配的应用角色:") for role in user_roles: print(f"- {role}") else: print(f"令牌获取失败:{result.get('error_description', result.get('error'))}")
场景2:桌面/移动应用(公共客户端,交互式流程)
适用于桌面APP直接引导用户登录的场景:
import msal # 替换为你的应用配置 CLIENT_ID = "你的应用客户端ID" TENANT_ID = "你的租户ID" AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}" SCOPE = ["User.Read", "openid", "profile"] # 初始化公共客户端 app = msal.PublicClientApplication( CLIENT_ID, authority=AUTHORITY ) # 交互式登录获取令牌 result = app.acquire_token_interactive(scopes=SCOPE) # 提取用户角色 if "id_token_claims" in result: user_roles = result["id_token_claims"].get("roles", []) print("用户已分配的应用角色:") for role in user_roles: print(f"- {role}") else: print(f"令牌获取失败:{result.get('error_description', result.get('error'))}")
场景3:获取用户的目录角色(如全局管理员)
如果需要获取Azure AD内置的目录角色,需调用Microsoft Graph API,步骤如下:
import msal import requests # 先按上述流程获取access_token # ...(省略令牌获取代码) if access_token := result.get("access_token"): # 调用Graph API获取目录角色 graph_endpoint = "https://graph.microsoft.com/v1.0/me/memberOf/microsoft.graph.directoryRole" headers = {"Authorization": f"Bearer {access_token}"} response = requests.get(graph_endpoint, headers=headers) if response.status_code == 200: directory_roles = response.json().get("value", []) print("用户的目录角色:") for role in directory_roles: print(f"- {role['displayName']}") else: print(f"Graph API调用失败:{response.text}")
注意事项
- 应用角色会包含在
id_token的roles声明中,仅当用户被分配了应用角色时才会返回该字段,未分配则返回空列表 - 获取目录角色需要额外的API权限(如
Directory.Read.All),需在Azure AD应用中配置并授予管理员同意 - 确保令牌请求的
scope包含openid,否则无法获取包含用户角色信息的id_token
内容的提问来源于stack exchange,提问作者Albert
相关产品推荐
相关产品推荐

