如何在 api (asp.net api) 中验证通过 spa (react app) 从 azure ad b2c 获得的访问令牌?
How to authenticate an access token which is obtained from azure ad b2c through an spa (react app), in a api (asp.net api)?
I have a react app as my client app and an asp.net api as my api (resources). I have managed to integrate azure ad b2c login in my client app. Now I am traying to send a request that contains the access token, to my api(which is now secured with azure ad b2c) to have access to my api resources. But I get status code 401 from the api that means unauthorized. I send the access token (bearer token) from client app (react) to the api like this:
const tokenItem = sessionStorage.getItem('item1');
const tokenjson = JSON.parse(tokenItem);
const accessToken = tokenjson.secret;
const tokenConfig = {
headers: { Authorization: `Bearer ${accessToken}` }
};
axios.post('https://localhost:44304/func', model, tokenConfig)
.then(response => {
this.setState({ Result: response.data });
})
.catch(error => {
console.log(error)
})
在 api 应用程序中,我在 Startup.cs
中有以下代码
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(options =>
{
Configuration.Bind("AzureAdB2C", options);
options.TokenValidationParameters.NameClaimType = "name";
},
options => { Configuration.Bind("AzureAdB2C", options); });
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseAuthentication();
app.UseAuthorization();
...
}
我的 appsettings.json 在 api 应用程序中是这样的:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AzureAdB2C": {
"Instance": "https://mytenantName.b2clogin.com",
"Domain": "mytenantName.onmicrosoft.com",
"ClientId": "my api client id ",
"SignUpSignInPolicyId": "B2C_1_mySignupSignin_userflow"
},
"AllowedHosts": "*"
}
我的控制器如下所示:
[Authorize]
[Route("[Controller]")]
[RequiredScope("user.read", "user.write")]
[ApiController]
public class TokenController : Controller
{
[HttpPost]
public async Task<IActionResult> Func([FromBody] CreateModel model)
{
some functions...
}
}
我应该说我可以在客户端应用程序中看到访问令牌(反应)。
为什么在向 api 发送请求后得到状态码 401?
我的代码有问题吗?我真的很感激任何帮助:)
看起来您正在尝试访问 Microsoft Graph API 而不是您的后端 api。 (因为你的范围是:“User.Read”,这只是微软图形 api 的范围)。
您的 front-end 应用需要为您的 API 使用范围,而不是 User.Read。这样它将获得一个访问令牌,该令牌适用于您的 API。通过公开 API 部分为您的 API 应用程序注册一个范围,并在您的 front-end 应用程序中使用该范围。
看起来如何
Note :Remove user.read permission which is for microsoft graph api.
I have a react app as my client app and an asp.net api as my api (resources). I have managed to integrate azure ad b2c login in my client app. Now I am traying to send a request that contains the access token, to my api(which is now secured with azure ad b2c) to have access to my api resources. But I get status code 401 from the api that means unauthorized. I send the access token (bearer token) from client app (react) to the api like this:
const tokenItem = sessionStorage.getItem('item1');
const tokenjson = JSON.parse(tokenItem);
const accessToken = tokenjson.secret;
const tokenConfig = {
headers: { Authorization: `Bearer ${accessToken}` }
};
axios.post('https://localhost:44304/func', model, tokenConfig)
.then(response => {
this.setState({ Result: response.data });
})
.catch(error => {
console.log(error)
})
在 api 应用程序中,我在 Startup.cs
中有以下代码public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(options =>
{
Configuration.Bind("AzureAdB2C", options);
options.TokenValidationParameters.NameClaimType = "name";
},
options => { Configuration.Bind("AzureAdB2C", options); });
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseAuthentication();
app.UseAuthorization();
...
}
我的 appsettings.json 在 api 应用程序中是这样的:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AzureAdB2C": {
"Instance": "https://mytenantName.b2clogin.com",
"Domain": "mytenantName.onmicrosoft.com",
"ClientId": "my api client id ",
"SignUpSignInPolicyId": "B2C_1_mySignupSignin_userflow"
},
"AllowedHosts": "*"
}
我的控制器如下所示:
[Authorize]
[Route("[Controller]")]
[RequiredScope("user.read", "user.write")]
[ApiController]
public class TokenController : Controller
{
[HttpPost]
public async Task<IActionResult> Func([FromBody] CreateModel model)
{
some functions...
}
}
我应该说我可以在客户端应用程序中看到访问令牌(反应)。 为什么在向 api 发送请求后得到状态码 401? 我的代码有问题吗?我真的很感激任何帮助:)
看起来您正在尝试访问 Microsoft Graph API 而不是您的后端 api。 (因为你的范围是:“User.Read”,这只是微软图形 api 的范围)。
您的 front-end 应用需要为您的 API 使用范围,而不是 User.Read。这样它将获得一个访问令牌,该令牌适用于您的 API。通过公开 API 部分为您的 API 应用程序注册一个范围,并在您的 front-end 应用程序中使用该范围。
看起来如何
Note :Remove user.read permission which is for microsoft graph api.