I am migrating from ADAL to MSAL then getting the Unauthorized error when passing token into my api. (using React and .NET core ( .NET core 2.1 framework)
UIClient application is already registered then I have added SPA and add redirecturl.
Registered API application has added UIClient ClientId into
Expose API -> Authrozied client application
MSAL is able to generate the token.
Sending token to API (using .Net core 2.1 framework)
Failed in authorizing the token, getting 401 unauthorized error from API code.
appsetting.json file contain setting
AzureAd{
Authority: "https://login.microsoftonline.com/common",
ValidClientIds: ["Guid1","Guid2"],
"AllowedIssuers: ["stsurl1","stsurl2"]
}
Startup.cs code
services.AddAuthentication(opt => {opt.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;}).AddAzureAdBearer(opt2 => configuration.Bind("AzureAd", opt2)); ```
Please check if the audience is matching the clientId of the
application of the token is decoded in https://jwt.ms/. Audience
mmatch the client iD and sometimes it maybe AppId URI of the app i.e;
something like api://<clientId>.So please try checking for the same
by changing or also including clientId as both clientId and appId
uri or allowing both audiences.
Also if thats not the issue try changing accessTokenAcceptedVersion
property of the in the Web API app manifest in azure ad portal to 1
or null if it is 2 or change to 2 if it is already 1 or null.
Also please make sure that the scope of your web api
(api:///) which is exposed after giving api permissions is granted admin consent either from portal
itself or check with the admin .
Related
Good Day,
Currently I have a single tenent with a React UI and .NET Core Apis secured by Azure Active Directory without any problems.
We have recently moved to a new Azure Tenent, new Active Directory etc. I have create two new App Registrations, one single App Service for UI and one for API. I have linked the App Service to AAD (UI = UI App Registration, API = API App Registration).
The problem is the API is getting a 401 error and I think see that in the original tenent the Bearer token is in a JWT format but in the new instance it's not, I believe it my be a graph api access key.
New Tenent:
Authorization: Bearer PAQABAAAAAAD--DLA3VO7QrddgJg7WevrQvEQVbZEMD8su-tIp9k2bTFUTort7SZgeDI52P6KRYefHgtmj4YrecgUKZJ2wylGuhvIzIz642n7Sg0VMU1RwKtrzWlaMqK62CaSoJcstxiEf6 *****
Orginal Tenent:
Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImtpZCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyJ9.eyJhdWQiOiI3OThkN2ZkOC0zODk2LTQxOGMtOTQ0Ny0wNGFlNTQ2OGFkNDIiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83ZDE3NTU3Ni03Y2Y3LTQyMDctOTA5My0wNmNiNmQyZDIwNjAvIiwiaWF0IjoxNjE2NDUyNzExLCJuYmYiOjE2MTY0NTI3MTEsImV4cCI6MTYxNjQ1NjYxMSwiYWNyIjoiMSIsImFpbyI6IkFTUUEyLzhUQUFBQU9mejhPZHp *****
Please someone kindly enought to provide some guidance / input where I am going wrong.
Regards
Paul.
When using Azure AD to obtain an access token, an additional resource parameter is required. Otherwise, the access token is not a JWT.
For example, if your web API's application ID URI is https://contoso.com/api and the scope name is Employees.Read.All, then with oidc-client the client configuration should be :
scope: 'openid profile email Employees.Read.All',
extraQueryParams: {
resource: 'https://contoso.com/api'
}
In App Service auth configuration, you can use additionalLoginParams
"additionalLoginParams": ["response_type=code", "resource=https://contoso.com/api"]
If you did not use a custom application ID URI, it may look like
api://868662dd-3e28-4c7f-b7d5-7ec02ac9c601
Quickstart: Configure an application to expose a web API
Firstly, the scope is incorrect.
You should Expose an API in your API App Registration and then add it as a permission in your UI App Registration. You can refer to this document.
And when you try to call the 'https://login.windows.net/{tenant}/oauth2/authorize endpoint, you need to specify the scope to include api://{app id of the API App Registration}. For example: api://{app id of the API App Registration} openid profile email. Then the access token would be for calling your API.
At last, for CORS issue, please configure the CORS as * in your web app to see if it helps.
Try to follow this step: Configure App Service to return a usable access token
In my experience, this problem occurs, when you try to authorize against version 1 of the endpoint.
Instead of calling
https://login.microsoftonline.com/{tenant}/oauth2/authorize
call
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
You might be required to set something like "metadata URL" in you authorization library to:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/.well-known/openid-configuration
Make sure your builder follows this order...lifted from our API program.cs
These must be in order of
UseRouting -> UseAuthentication -> UseAuthorisation -> MapControllers
> app.UseRouting()
> app.UseAuthentication()
> app.UseAuthorization()
> app.MapControllers()
If app.UseAuthentication and app.UseAuthorization are not in this order in statement position you Will get 401 Unauthorised as at 01/2023 .Net 6 Core.
At work we are making an SPFx Web Part React client app that deploys to SharePoint as a Web Part. Our back-end is a ASP.NET Core 2.2 Web API that is secured using Azure Portal's built in Authentication feature. The front-end is using AadHttpClient that magically handles the authentication by taking the context of the current page (SharePoint) that has the user already logged in. Doing so, silent authentication occurs and the API call is successfully made with authentication successfully passed. The AadHttpClient is supposed to magically bundle up the token in the request header that gets sent to the back-end Web API. I still need to debug the live development app and see how to retrieve the Bearer Token in the back-end Web API. These are my next probable steps?
Would I just probably use 'string bearerToken = Request.Headers.....;' or 'string bearerToken = Request.Headers["KeyValue"]' to get the token itself?
Assuming I can get this Bearer Token, how can I check the caller's user information? Is it just var userName = User.Identity.Name;? Or would I or could I use the token and some how make a call to Microsoft Graph API to view the user's info?
If you are using ASP.NET Core and using default authentication then things are bit easier. From documentation you can see that several tokens are injected in the request header based on Identity provider so in your case you have to look for following headers which Azure AD injects. These headers would contain ID Token which you would need to verify the claims and get user information.
X-MS-TOKEN-AAD-ID-TOKEN
X-MS-TOKEN-AAD-ACCESS-TOKEN
X-MS-TOKEN-AAD-EXPIRES-ON
X-MS-TOKEN-AAD-REFRESH-TOKEN
Ideally all the claims are injected automatically in ClaimsPrincipal
you can find more here
Official Docs
How To extract Token
I'm trying to use AzureAD to get a token in swagger and test my .netCore2.1 API with it.(using Swashbuckle.AspNetCore 4.0.1)
To do this I completed the following steps
1. Created a Web API project(asp.net Core2.1)
2. Register an Azure AD (AAD) app for the Web API
3. Updated the Web API project to use Azure AD authentication
4. Register an AAD app for the Swagger web site https://localhost:5001/swagger
5. Granted permissions for the Swagger AAD app to access the Web API AAD app
6. Generated a Client Secret for the Swagger AAD app
7. Enabled OAuth2 implicit flow on the Swagger AAD app
8. Added Swagger to the Web API project
When I authenticate, I am getting the following error.
Error AADSTS500013: Resource identifier is not provided .
When I click authorize
I am getting error AADSTS500013: Resource identifier is not provided.
My WebAPI project's startup.cs file goes here
Please help me understand which resource Identifier I am missing here or how to resolve this error.
Or any pointers on how to use Swaggerbuckle with ASP.NET Core webAPI, especially with AAD authenticated WebAPI ?
UPDATES
I copied my webAPI's APPID URI from azure portal. ie Dashboard>>Microsoft - App registrations>>MY_API_APP>>Settings>>Properties>>App ID URI
But I am still getting the same error when I try to authenticate
Error AADSTS500013: Resource identifier is not provided
Usually resource identifier which uniquely identifies your application. You can easily found your resource Identifier Like below:
When logged into the Azure portal, Azure Active Directory > App Registrations > [App Name] > Settings> Properties, then it's the App ID URI
See the screen shot:
In the orignal OAuth 2.0 specification, there is no resource parameter in the authorization request. It use scope parameter. The authorization and token endpoints allow the client to specify the scope of the access request using the "scope" request parameter.
As document explains, when Azure AD implement the OAuth 2.0(1.0 endpoint), the resource is used to specify the access_token you request for which resource. And the Azure AD will issue the token which the scp based on the permission you config on the portal for the resource.
And in the v2.0 endpoint, the Azure AD also use the scope to support the dynamic permission request. More detail you can have a look here.
Usual Reason for Error
Make sure you have configured below steps accordingly.
Like below:
Application Manifest
Reply URI
Request Endpoint
For V1.0 refer this URI https://login.microsoft.com//oauth2/authorize
For V2.0 refer this URI https://login.microsoft.com//oauth2/v2.0/authorize
Application Consent
Need to confirm your application required resource access permission you could refer here
I believe this step can lead you to sort out your problem.
With Azure AD V1.0 app you need set resource to identify which api you want to access during the authentication&access token requests :
Code flow :
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code
Implicit flow :
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-implicit-grant-flow
In Swashbuckle.AspNetCore 4.0.1 , you need to config the resource as parameter if you want to get access token for accessing your web api :
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "MySite API V1");
options.OAuthClientId("19c73866-562f-482a-bafb-89d9fe9b0aaa");
options.OAuthAppName("Swagger Api Calls");
// add resource
options.OAuthAdditionalQueryStringParams(new Dictionary<string, string>() { { "resource", "f479db30-9b62-431b-98c2-bcaae52203cf" } });
});
For us Nan Yu's response got us one step closer.
We added the resource in the AdditionalQuerystringParams like so:
options.OAuthAdditionalQueryStringParams(new Dictionary<string, string>() { { "resource", "{ResourceIDHere}" } });
We are now able to get passed the Auth step in Swagger, but trying routes out doesn't seem to pass the token to the api called and so we get a 401 Error.
change { "scope", API_AppID_URI} to { "resource", API_AppID_URI}
I have a working Azure Mobile .NET backend which has a requirement to expose data securely through a TableController.
The table controller has the the [Authorize] attribute on the controller class definition and I have Token Store Enabled in the Azure Portal's Authentication / Authorization blade.
I'm using the following code to get the user's credentials passed by the mobile client app:
var creds = await this.User.GetAppServiceIdentityAsync(this.Request);
However, when deployed to the Azure portal this always returns a NULL exception; digging deeper I can see "Exception=System.ArgumentOutOfRangeException: The 'principal' parameter must be of type 'ClaimsPrincipal'."
Using JWT.IO, I've inspected the token being passed from the client app and the token looks 100% correct.
With the backend deployed to the Azure Portal and a breakpoint set I see that this.User is null!
How do I get access to the user's credentials, has anyone got this working?
Cheers,
Iain
Hi so I have been trying to make an app that uses a Biq Query API.
All the authentication and client secrets for OAuth2 work fine when I load the app locally, however after deploying the code I get the following error:
Error: redirect_uri_mismatch
Request Details
scope=https://www.googleapis.com/auth/bigquery
response_type=code
redirect_uri=https://terradata-test.appspot.com/oauth2callback
access_type=offline
state=https://terradata-test.appspot.com/
display=page
client_id=660103924069.apps.googleusercontent.com
But looking at my API Console, I find that the redirect uri https://terradata-test.appspot.com/oauth2callback is in my list or redirect uri's:
Redirect URIs:
1.https://terradata-test.appspot.com/oauth2callback
2.http://terradata-test.appspot.com/oauth2callback
3.http://1.terradata-test.appspot.com/oauth2callback
4.https://code.google.com/oauthplayground
I'm not sure what I'm missing to fix this problem? Why is there a redirect error with a uri that is listed in the API console?
The app builds the OAuth2 decorator to pass through to the Biq Query API like this:
CLIENT_SECRETS = os.path.join(os.path.dirname(__file__),
'client_secrets.json')
decorator = oauth2decorator_from_clientsecrets(
CLIENT_SECRETS,
'https://www.googleapis.com/auth/bigquery')
http = httplib2.Http(memcache)
bq = bqclient.BigQueryClient(http, decorator)
Is there any more code I should put to clarify the situation? Any input would be greatly appreciated. Thanks so much!
Shan
In standard web server OAuth 2.0 flows (authorization code), there are 3 places the redirect_uri is used. It must be identical in all three places:
In the URL you redirect the user to for them to approve access and
get an authorization code.
In the APIs console
In the
server-to-server HTTPS post when exchanging an authorization code
for an access token (+ maybe a refresh token)
You haver to create an API credentials with next steps on
https://console.cloud.google.com/apis/credentials
Client Oauth Id
Web Type
JavaScript authorized -> https://yourapp.appspot.com
URIs authorized -> https://yourapp.appspot.com/oauth2callback
This is the credentials you have to use in local app before deploy