Azure IAM带MFA的OAuth2流程如何用curl获取access_token
问题描述
我尝试通过OAuth2从Azure IAM获取用户的access_token,编写了如下curl命令:
curl \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "scope=openid" \ -d "response_type=id_token+access_token" \ -d "grant_type=password" \ -d "client_id=${MY_APP_ID}" \ -d "username=${MY_USER}" \ -d "password=${MY_PASS}' \ 'https://login.microsoftonline.com/${MY_TENANT_ID}/oauth2/v2.0/token'
但收到错误:
{"error":"invalid_grant","error_description":"AADSTS50158: External security challenge not satisfied. User will be redirected to another page or authentication provider to satisfy additional authentication challenges...
我们启用了MFA,但curl调用未触发验证,请问在带MFA的OAuth2流程中正确获取access_token的方法是什么?
解决方案
你使用的**密码授权流(grant_type=password)**不支持MFA验证,这是触发AADSTS50158错误的核心原因——Azure AD要求用户完成MFA,但该流程无法处理交互式验证步骤。
要支持MFA,必须采用交互式授权流程,推荐使用授权码流(Authorization Code Flow),具体步骤如下:
1. 获取授权码
构造授权请求URL,引导用户在浏览器中完成登录(包含MFA验证):
https://login.microsoftonline.com/${MY_TENANT_ID}/oauth2/v2.0/authorize? client_id=${MY_APP_ID} &response_type=code &redirect_uri=https://your-redirect-uri.com/callback &scope=openid+offline_access+{your-additional-scopes} &response_mode=query
用户完成验证后,会被重定向到指定的redirect_uri,URL中会携带code参数,即授权码。
2. 用授权码换取access_token
拿到授权码后,通过curl调用token端点获取令牌:
curl \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "client_id=${MY_APP_ID}" \ -d "scope=openid+offline_access+{your-additional-scopes}" \ -d "code={authorization-code-from-step1}" \ -d "redirect_uri=https://your-redirect-uri.com/callback" \ -d "grant_type=authorization_code" \ -d "client_secret=${MY_APP_SECRET}" # 机密客户端需添加此参数 'https://login.microsoftonline.com/${MY_TENANT_ID}/oauth2/v2.0/token'
非交互式场景替代方案
如果是服务端自动化等无交互场景,可以选择以下方式:
- 服务主体+客户端凭证流:使用服务主体身份而非用户身份,通过客户端凭证流获取令牌,无需用户参与,不受MFA限制。
- 设备授权流:适合无浏览器的设备,用户可在其他设备上完成MFA验证,流程无需本地浏览器支持。
内容的提问来源于stack exchange,提问作者Bernard Halas
相关产品推荐
相关产品推荐

