Azure AD无需浏览器的授权码许可流实现,获取MS Graph访问令牌方案咨询
可行实现方案
你需要的场景完全适配设备代码流(Device Code Flow),这是Azure AD专门为无头、无浏览器、SSH登录这类场景设计的OAuth2授权流,不需要在运行程序的服务器上启动浏览器,也不需要用户将账号密码作为参数传入程序,完全符合你的需求。
第一步:调整Azure AD应用配置
- 登录Azure Portal进入对应的AD应用配置页,找到身份验证选项卡,将「允许公共客户端流」的开关设置为开启,该配置是设备代码流的必要前提,无需额外配置重定向URI。
- 在「API权限」选项卡中配置程序需要的MS Graph委托权限,可根据需要选择是否由管理员提前为全租户同意该权限,否则用户第一次授权时会需要自行同意权限申请。
第二步:程序实现逻辑
- 程序启动后调用Azure AD设备码申请端点,会返回三个核心内容:用户验证地址
https://microsoft.com/devicelogin、用户需要输入的验证代码、代码过期时间。 - 程序直接将验证提示打印到命令行,告知用户使用已经配置了MFA的设备(手机等)访问上述地址,输入验证代码后完成MFA验证即可,全程不需要在SSH连接的服务器上做任何额外操作。
- 程序后台自动轮询Azure AD令牌端点,直到用户完成验证或者验证代码过期,验证通过后即可直接获取到access token和refresh token,后续即可使用access token调用MS Graph接口。
示例代码(Python MSAL SDK)
import msal # 替换为你自己的AD应用配置 CLIENT_ID = "你的Azure AD应用客户端ID" TENANT_ID = "你的Azure AD租户ID" # 按需替换为你需要的MS Graph权限列表 REQUEST_SCOPES = ["User.Read", "Directory.Read.All"] # 初始化公共客户端实例 msal_app = msal.PublicClientApplication( client_id=CLIENT_ID, authority=f"https://login.microsoftonline.com/{TENANT_ID}" ) # 发起设备码授权流 device_flow = msal_app.initiate_device_flow(scopes=REQUEST_SCOPES) if "user_code" not in device_flow: raise Exception(f"申请设备码失败: {device_flow.get('error_description', '未知错误')}") # 打印用户操作提示 print(device_flow["message"]) # 轮询等待用户完成验证,获取令牌 token_result = msal_app.acquire_token_by_device_flow(device_flow) if "access_token" in token_result: print("✅ 访问令牌获取成功,可发起MS Graph请求") # 后续调用MS Graph时在请求头携带Authorization: Bearer {token_result['access_token']}即可 else: print(f"❌ 令牌获取失败: {token_result.get('error_description', '未知错误')}")
额外优化建议
- 主流开发语言都有官方的MSAL SDK支持设备代码流,直接使用官方SDK即可,不需要手动实现OAuth2流的逻辑,避免安全问题。
- 如果需要降低用户重复验证的频率,可以将获取到的refresh token加密存储在运行程序的用户家目录下,下次程序启动时优先尝试用refresh token刷新访问令牌,只有刷新失败时再重新发起设备码流。
- 不需要收集用户的用户名和密码作为程序入参,设备码流完全规避了明文传递、存储用户凭据的风险,安全性更高。
内容的提问来源于stack exchange,提问作者bobocu
相关产品推荐
相关产品推荐

