I have successfully implemented OAuth 2.0 authorization into a .NET 8 service and was able to consume it in both Postman and Swagger (using pkce).
However when it came time to consume it through another .NET service, I encountered issues.
I have been able to obtain the token, but I still get a http 403 error when attempting to consume the service endpoint.
This is my Authorize()
method:
var authority = $"https://login.microsoftonline.com/{_config.TennantId}/oauth2/v2.0/token";
var app = ConfidentialClientApplicationBuilder
.Create(_config.ClientId)
.WithClientSecret(_config.ClientSecret)
.WithAuthority(authority)
.Build();
var result = await app.AcquireTokenForClient(new string[] { $"{_config.Scopes}" })
.ExecuteAsync();
This is the authorization configuration on the target app:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration);
This is the controller of the target app:
[Authorize]
[RequiredScope("WriteOperations")]
[ApiController]
public class CustomersController : ControllerBase
I know that for Postman and swagger one needs to provide a redirect Url. But the documentation I found for backend to backend flows, doesn’t include any mention of one.
What am I doing wrong and how can I fix this?
2
Answers
For everyone dealing with this issue, when you create a permission in the App Registration in EntraID, you need to also provide admin consent to that permission. It's necessary for the Client Credentials flow, which the code in my question uses. I've made request before and after granting admin consent, in order to make sure that was the issue. It'll work without for Authorization Code flow, though.
As about missing scope, which was mentioned by the submitted answer above and the comment to the post, that's not the case. Client Credentials flow only allows for .default scope.
The 403 error usually occurs if the access token does not contain required scopes to call the API.
AcquireTokenForClient
flow generates access token without user interaction and performs a client-to-client flow.Created a Microsoft Entra SPA application and exposed an API, added scope like below:
Granted API permissions:
For sample, generated tokens via Postman:
To do the same via code, you need to make use of
AcquireTokenByAuthorizationCodeParameterBuilder WithPkceCodeVerifier
flow notAcquireTokenForClient
flow or any other user interactive flow based on your requirement refer this MsDocFor complete code, refer this GitHub blog.
AcquireTokenByAuthorizationCode
Refer this SO Thread by me.Make sure to decode the access token and check the
scp
andaud
claim is populated correctly:Reference:
How to implement a PKCE code challenge in C# | Nicola Iarocci