在 Azure Active Directory B2C 中使用 OpenID Connect 进行 Web 登录会得到 id_token 而不是 access_token
Web sign-in with OpenID Connect in Azure Active Directory B2C gives id_token instead of access_token
我正在遵循 Microsoft 的指南:
https://docs.microsoft.com/en-us/azure/active-directory-b2c/openid-connect
发送第一个身份验证请求会得到预期的 code
和 id_token
响应。
GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=code+id_token
&redirect_uri=https%3A%2F%2Faadb2cplayground.azurewebsites.net%2F
&response_mode=form_post
&scope=openid%20offline_access
&state=arbitrary_data_you_can_receive_in_the_response
&nonce=12345
.ts 文件,Microsoft 示例值,但为清楚起见添加。
export const login = async () => {
// window.location.origin is safe due to specified Redirect URIs for ADB2C
window.location.href = "https://{tenant}.b2clogin.com/tfp/{tenant}.onmicrosoft.com/B2C_1_signupsignin/oauth2/v2.0/authorize?"
+ "client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6"
+ "&nonce=anyRandomValue"
+ "&redirect_uri=" + window.location.origin + "/signin-oidc"
+ "&scope=openid%20offline_access"
+ "&response_type=code+id_token";
}
但是获取令牌请求:
POST {tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token HTTP/1.1
Host: {tenant}.b2clogin.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6&scope=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...&redirect_uri=urn:ietf:wg:oauth:2.0:oob
根据例子应该return这样:
{
"not_before": "1442340812",
"token_type": "Bearer",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
"scope": "90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access",
"expires_in": "3600",
"refresh_token": "AAQfQmvuDy8WtUv-sd0TBwWVQs1rC-Lfxa_NDkLqpg50Cxp5Dxj0VPF1mx2Z...",
}
我得到的是一个新的 id_token
:
{
"id_token": "eyJ0eXAiOiJKV...",
"token_type": "Bearer",
"not_before": 1602766192,
"id_token_expires_in": 3600,
"profile_info": "eyJ2ZXIiOiIxL...",
"scope": "offline_access openid",
"refresh_token": "eyJraWQiOiJjc...",
"refresh_token_expires_in": 1209600
}
C#:
var client = _clientFactory.CreateClient();
var kvpList = new List<KeyValuePair<string, string>>();
kvpList.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
kvpList.Add(new KeyValuePair<string, string>("client_id", "90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6"));
kvpList.Add(new KeyValuePair<string, string>("scope", "90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access"));
kvpList.Add(new KeyValuePair<string, string>("code", {code}));
kvpList.Add(new KeyValuePair<string, string>("redirect_uri", HttpContext.Request.Scheme + "://" + HttpContext.Request.Host + "/signin-oidc"));
kvpList.Add(new KeyValuePair<string, string>("client_secret", "{mySecret}"));
var req = new HttpRequestMessage(HttpMethod.Post, "https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/B2C_1_signupsignin/oauth2/v2.0/token")
{ Content = new FormUrlEncodedContent(kvpList) };
using var httpResponse = await client.SendAsync(req);
var response = await httpResponse.Content.ReadAsStringAsync();
我错过了什么?
当您请求“openid offline_access”时,您只需要 id-token 和一个刷新令牌。要获取访问令牌,您需要请求与您要访问的 resource/API 关联的范围。
确实是范围错误。从您的 Azure AD B2C 应用程序注册或应用程序(旧版)中获取它。
我的例子被阅读了
https://{tenant}.onmicrosoft.com/90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6/read
TS:
"&scope=openid%20offline_access%20https://{tenant}.onmicrosoft.com/90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6/read"
C#:
kvpList.Add(new KeyValuePair<string, string>("scope", "openid offline_access https://{tenant}.onmicrosoft.com/90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6/read"));
在此之后一切正常。
我正在遵循 Microsoft 的指南:
https://docs.microsoft.com/en-us/azure/active-directory-b2c/openid-connect
发送第一个身份验证请求会得到预期的 code
和 id_token
响应。
GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=code+id_token
&redirect_uri=https%3A%2F%2Faadb2cplayground.azurewebsites.net%2F
&response_mode=form_post
&scope=openid%20offline_access
&state=arbitrary_data_you_can_receive_in_the_response
&nonce=12345
.ts 文件,Microsoft 示例值,但为清楚起见添加。
export const login = async () => {
// window.location.origin is safe due to specified Redirect URIs for ADB2C
window.location.href = "https://{tenant}.b2clogin.com/tfp/{tenant}.onmicrosoft.com/B2C_1_signupsignin/oauth2/v2.0/authorize?"
+ "client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6"
+ "&nonce=anyRandomValue"
+ "&redirect_uri=" + window.location.origin + "/signin-oidc"
+ "&scope=openid%20offline_access"
+ "&response_type=code+id_token";
}
但是获取令牌请求:
POST {tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/token HTTP/1.1
Host: {tenant}.b2clogin.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6&scope=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrq...&redirect_uri=urn:ietf:wg:oauth:2.0:oob
根据例子应该return这样:
{
"not_before": "1442340812",
"token_type": "Bearer",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
"scope": "90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access",
"expires_in": "3600",
"refresh_token": "AAQfQmvuDy8WtUv-sd0TBwWVQs1rC-Lfxa_NDkLqpg50Cxp5Dxj0VPF1mx2Z...",
}
我得到的是一个新的 id_token
:
{
"id_token": "eyJ0eXAiOiJKV...",
"token_type": "Bearer",
"not_before": 1602766192,
"id_token_expires_in": 3600,
"profile_info": "eyJ2ZXIiOiIxL...",
"scope": "offline_access openid",
"refresh_token": "eyJraWQiOiJjc...",
"refresh_token_expires_in": 1209600
}
C#:
var client = _clientFactory.CreateClient();
var kvpList = new List<KeyValuePair<string, string>>();
kvpList.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
kvpList.Add(new KeyValuePair<string, string>("client_id", "90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6"));
kvpList.Add(new KeyValuePair<string, string>("scope", "90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access"));
kvpList.Add(new KeyValuePair<string, string>("code", {code}));
kvpList.Add(new KeyValuePair<string, string>("redirect_uri", HttpContext.Request.Scheme + "://" + HttpContext.Request.Host + "/signin-oidc"));
kvpList.Add(new KeyValuePair<string, string>("client_secret", "{mySecret}"));
var req = new HttpRequestMessage(HttpMethod.Post, "https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/B2C_1_signupsignin/oauth2/v2.0/token")
{ Content = new FormUrlEncodedContent(kvpList) };
using var httpResponse = await client.SendAsync(req);
var response = await httpResponse.Content.ReadAsStringAsync();
我错过了什么?
当您请求“openid offline_access”时,您只需要 id-token 和一个刷新令牌。要获取访问令牌,您需要请求与您要访问的 resource/API 关联的范围。
确实是范围错误。从您的 Azure AD B2C 应用程序注册或应用程序(旧版)中获取它。
我的例子被阅读了
https://{tenant}.onmicrosoft.com/90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6/read
TS:
"&scope=openid%20offline_access%20https://{tenant}.onmicrosoft.com/90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6/read"
C#:
kvpList.Add(new KeyValuePair<string, string>("scope", "openid offline_access https://{tenant}.onmicrosoft.com/90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6/read"));
在此之后一切正常。