Authorization has been denied for this request. Postman - c#

New to Owin authorization and currently exploring.
I can now successfully get the token from the token host
I now try to access a controller with the [Authorize] attribute but seem to be getting a Authorization has been denied for this request issue.
I used the returned token as a bearer token but doesnt seem to work in post man. Any help would be appreciated.
Thanks

Shoot it was just a matter of order in the Startup.cs
I created called ConfigureAuth after WebApiConfig.Register(config); #.#

Related

Azure AD Authentication : Multiple Scopes Issue

I am likely expecting or doing something that is not correct. Need some help in getting back to the right path.
Simple Usecase - How to configure a client so it can request a token with all the right scopes? currently I am running it via postman but actual client is going to be a react app using msal.
Setup:
App Registration in Azure.
API Permissions:
Microsoft.Graph --> email & User.Read
Exposed an API:
Scope URI: api://someguid
One Scope is Added : api//someguid/testscope
Net Core 6 API
AppSettings.Json
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Audience":"api//someguid"
"ClientId": "my-client-id",
"TenantId": "my-tenant-id"
},
"Graph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "user.read,email"
}
}
Middleware
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration, Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(Configuration.GetSection("Graph"))
.AddInMemoryTokenCaches();
This is how I am calling graph in Controller.
[Authorize]
public class AbcController: Controller
{
private readonly GraphServiceClient _graphClient;
public AbcController(GraphServiceClient graphClient)
{
_graphClient = graphClient;
}
[HttpGet("get-me")]
public async Task<ActionResult> GetSomeDetails()
{
var user = await _graphClient.Me.Request().GetAsync();
return null;
}
I run this via postman with Auth Code flow with PKCE, Here are the issues
When I set the Scope as : api//someguid/testscope
Call gets authenticated and the Token is acquired correctly in postman
The API get-me get authorized correctly
But the call _graphClient.Me.Request().GetAsync() throws throws a 500 error
Also, a direct call to https://graph.microsoft.com/v1.0/me in postman using the token
gives insufficient privilege error
When I set the scope as : api//someguid/testscope https://graph.microsoft.com/email
Call gets authenticated But the acquire token fails with incorrect scope
When I set the scope as : https://graph.microsoft.com/email https://graph.microsoft.com/user.read
Call gets authenticated and the acquire token is acquired
Direct call to https://graph.microsoft.com/v1.0/me works as expected
But now my API does not get Authorized and gives 401
Can someone suggest what am i missing in my setup or if i am doing something crazy wrong?
All i am looking to do is get my API authorized, and get the email address pulled from graph in the API, without explicitly re-acquiring the token or specifying my client secret in the API to build the graph client.
This was taken as an input to try and build my poc
https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-web-api-call-api-call-api?tabs=aspnetcore
Note that, one token can only be issued to one audience. You cannot acquire access token for multiple audience (Ex: custom API and MS Graph) in single call.
In your scenario, you need to make two separate requests for acquiring access tokens i.e., one for your API and other for Microsoft Graph.
I tried to reproduce the same in my environment via Postman and got below results
I registered one Azure AD application and added same API permissions as below:
Now I exposed one API named testscope same as you like below:
Make sure to select Single-page application while adding Redirect URIs to your application like below:
I acquired token successfully using Auth code flow with PKCE from Postman like below:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
client_id:<appID>
grant_type:authorization_code
scope: api://someguid/testscope
code:code
redirect_uri: https://jwt.ms
code_verifier:S256
The above token won't work for calling Microsoft Graph /me endpoint and works only to authorize API based on its audience.
To check the audience of above token, decode it in jwt.ms like below:
To call /me endpoint for mail, you need to acquire token again with Microsoft graph scope without configuring client secret like below:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
client_id:<appID>
grant_type:authorization_code
scope: https://graph.microsoft.com/.default
code:code
redirect_uri: https://jwt.ms
code_verifier:S256
The above token won't work for authorizing API whereas you can call Microsoft Graph based on its audience.
To check the audience of above token, decode it in jwt.ms like below:
When I call /me endpoint using above token, I got the results successfully with mail like below:
References:
Azure AD Oauth2 implicit grant multiple scopes by juunas
reactjs - azure msal-brower with nextJs: passing only one scope to the API

C# .NET 5.0 MVC JWT Middleware authorization header

The problem is that when I login in through the MVC controller post method, i get the JWT token and save it in the HttpContext authorization header, the code jumps to middleware where i can see the token in the context, but as soon as the invoke functions call _next(context) delegate, there is no more authorization header. How do i solve this? Is there some good practice how to pass the token from mvc controller to the middleware so i could attach account to the context?
Thank you very much
One idea is that you need to set the SaveToken to true here:
.AddOpenIdConnect(options =>
{
...
options.SaveTokens = true;
If not, can you post our startup class to the question?
Storing the token in HttpContext.Session solved the problem. Thanks though.

JWT from AzureAD gives 403 Forbidden in .NET core API

I have an asp.net core API that works with JWT authentication. Roles are used for authorization, I use no scopes. Things work fine with both Auth0.com and ADFS, I am having trouble however with AzureAD. I get a JWT from AzureAD, which looks fine. However, then this happens:
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[2]
Successfully validated the token.
dbug: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[8]
AuthenticationScheme: Bearer was successfully authenticated.
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[13]
AuthenticationScheme: Bearer was forbidden.
I am at a loss as to what is the cause of this. Also, I am having a hard time getting more details as why authorization fails.
The only difference I see between a JWT from for example Auth0.com and AAD, is the lack of a "azp" claim, and the lack of a "scope" claim. The token from AAD has a "scp" claim. However, I am unable to find any documentation about wether this could result in this situation, or if something else could be the cause.
Any ideas, also about how to get more details, are welcome! Thanks.
Meanwhile I was able to solve this issue. For future reference I am posting the solution here.
There is a "roles" claim in the access token that comes from AAD, but for reasons rather unclear to me, with AAD as an identity provider, I have to check for "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" as the role claim.
This code works for both Auth0, ADFS and AAD:
var roleClaim = Configuration["JwtOptions:RoleClaim"];
if (string.IsNullOrWhiteSpace(roleClaim)) roleClaim = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
services.AddAuthorization(options =>
{
options.AddPolicy("role1", policy => policy.RequireClaim(roleClaim, "role1", "role2"));
options.AddPolicy("role2", policy => policy.RequireClaim(roleClaim, "role2"));
});
If someone can shed some light on why this is so, I'd be very interested. For now, I'm happy to have solved this.

Azure AD Authentication With Auth0

I created an Azure API App and set the [Authorize] attribute on my controller and published it to Azure. Then I registered an Auth0 app, providing the data from my AD app, following Auth0's documentation. When I test the connection on their site it works just fine. I can also log in fine in my app and retrieve the access token with:
var auth0 = new Auth0Client("myUrl", "myTenant");
var user = await auth0.LoginAsync();
var accessToken = user.IdToken;
However, when I make a request to my API, passing the access token in the Authorization header, it just throws an error 401 (Unauthorized). From what the documentation says, I was under the impression this is all that should be needed, and I've not found any information to suggest otherwise. Is there an additional step to linking these?
The Solution is to configure ur API to accept tokens by that issuer, like for example by using owin middleware app.UseJwtBearerAuthentication(). Glad I could help!

Handle bad access_token sent through request using Web API 2 C#

Hi I am using Bearer authentication in my web api 2. After user login i generate access token to the user. Further when they request my web api, they have to send access token in request header. All valid access tokens are requesting web api with out any problem. But I am not sure how to handle bad access tokens (expired). Please let me know the solution if you have. Thanks in advance.
In addition to Mahesh Kava, you may extend AuthorizeAttribute class to return more detailed information for unauthorized request. Refer to this SO question
You should use the [Authorize] filter attribute to authorize the request. All bad request with expired tokens will be treated with a 401 unauthorized error

Categories

Resources