Calling my own API secured by AzureAD V2 from another tenant - multi-tenant

I have a DotNet Core WebAPI living in my own Azure AD tenant. This WebAPI is secured via AzureAD V2 (!) BearerToken authentication. This API is called by an Angular SPA authenticated via OIDC (AzureAD v2) using #azure/msal-angular following the tutorial at https://learn.microsoft.com/en-us/graph/tutorials/angular. Everything works fine with users from my own tenant. But when logging in with a user from another tenant I get the following error:
"AADSTS650052: The app needs access to a service
(\\\"https://mytenant.de/AngularDemoApi2\\\") that your organization
\\\"myorganization.de\\\" has not subscribed to or enabled. Contact your
IT Admin to review the configuration of your service
subscriptions.\r\nTrace ID: 9597578e-7e48-49b2-85be--b5a1ee14300\r\n
Correlation ID: 30d4caf2-e3ca-4d7d-84b5-564d428e4e69\r\n
Timestamp: 2019-06-13 15:40:46Z|invalid_client"
I have tried to following some examples to make the WebApplication and the WebAPI multitenant but all the examples seem to be outdated and/or not relevant for V2 of Azure AD. WebApplication and WebAPI have set
"signInAudience": "AzureADandPersonalMicrosoftAccount"
in Manifest. WebAPI has App Uri in the form of
https://mytenant.de/AngularDemoApi2"
I guess that I need to give users from other tenants somehow permission to access the WebAPI in my tenant but I don't know how.
Edit: When I choose to expose the API directly from the app registration of the SPA it works like a charm. But this approach does not seem to be right because each exposed API would have the same audience ("aud" claim, the same audience as the SPA application). In my example above I have a separate app registration - one for the SPA and one for the API. This way each API would have it's own audience and it will also be mentioned in the consent screen.
May be someone could explain how to configure it correctly?

I had the same problem, and for me the solution was to add the client as an "authorized client application" to the WebAPI's app registration in the Azure portal.
This will show up in the service app's manifest as a section in the following form, where appId is the application id of the client app, and permissionIds contains the ids of the scopes requested by the client app, which can be read from the "oauth2Permissions" section of the manifest:
"preAuthorizedApplications": [
{
"appId": "523ca2d4-680b-4ef4-8a8c-3f3486693cf7",
"permissionIds": [
"35e5e006-83c5-4f37-a3bf-c048ee8c8600"
]
}
],
In your case, you might have to first register the Angular SPA as a client application in order to get a client id. This is described in this quickstart.

Related

Is there a way to Get username & id of current user in Remote Bff Api Endpoint

Can someone guide me or put me in the right direction? I'm new with microservices and Identityserver. I googled it but it's mostly about doing in mvc app that's not my scenario.
I have 3 projects in my .sln file
FrontendHost //Bff frontend dotnet react app
IdentityService //Asp.net mvc app Duende IdentityServer 6 for protecting Apis. Added claims here are openid, profile, email
BackendApi1 //.net6 web api that is protected using Remote Bff Api Endpoint approach.
I've a string Created By field in a model inside BackendApi1 project and in its api controller I wanna assign it with current signed-in user's name.
I tried with
var user = User.Identity.GetUserId();
But didn't get the expected result.

Using two azure AD app registrations for mobile and web

I have a mobile app which gets token directly from azure login. And I have a service which is using adal4j in spring boot. I cannot use the mobile generated token to authenticate spring service. Becase I use two different azure app registrations for mobile and web service. Is there a way to accomplish this ?
My understanding is that you have created 2 Enterprise Applications in Azure.
1) An Enterprise Application for your mobile app (Type: Native)
2) An Enterprise Application for your Web API app (Type: WebAPI)
For native app, you will not need a client secret but you will need a client secret for the Web API app.
Now coming to the key configurations:
In both of these, please update the manifest file to have oauth2AllowImplicitFlow set to true
Also, in your Web API Enterprise Application, please have the app id of your native app in the known client apps
"knownClientApplications": ["
Now, when calling your Web API through an end-point from the Native application, pass your token in your request header as "Authorization": "Bearer "
Also note: if you need to retrieve group claims, please update the manifest in both your enterprise apps to have the following setting for this property
"groupMembershipClaims": "SecurityGroup"
Update:
Under permissions in the native app, please add the Web API app registration to allow access
Yes, the OAuth 2.0 on-behalf-of flow should applies to your scenario. These steps constitute the On-Behalf-Of flow.
Azure AD issues a token for certain resource (which is mapped to an Azure AD app). When we call AcquireToken(), we need to provide a resourceID, only ONE resourceID. The result would have a token that can only be used for the supplied resource (id). There are ways where you could use the same token , but it is not recommended as it complicates operations logging, authentication process tracing, etc. Therefore it is better to look at the other options provided by Azure and the ADAL library. The ADAL library supports acquiring multiple access-Tokens for multiple resources using a refresh token. This means once a user is authenticated, the ADAL’s authentication context, would be able to generate an access-token to multiple resources without authenticating the user again.
Further details here.

Azure AD exchange access_token with id_token v.1.0 endpoint

I will draw a scenario, and need some suggestions:
I'm using Azure AD (v1.0 endpoint), a single-page app (SPA) and a web API. The SPA establishes the user's identity using OpenID Connect, authenticates the user and receives an id_token and access_token for the back-end web API.
Now, we don't want the SPA to do access control decision based on the id_token received within the SPA app.
Instead, the SPA sends the access_token to the back-end web API to access it, and now we want back-end web API to make an access control decision based on the roles claim found in the id_token, but which the back-end does not receive from the SPA.
The question is, is it possible for the back-end web API to send received access_token to Azure AD token endpoint and receive the relevant id_token for the user so that the back-end web API receives an id_token containing the roles claims for the user, in order to make an access control decision?
There are a couple issues with the approach as you describe it:
The app roles would be defined on the native client application (the SPA). Though you can technically define app roles in the manifest, you'll notice the Azure portal won't let you assign users or groups to a native client app. (Which sort of makes sense, because, as you've rightly said, you don't want to do any access control in the native client app.)
You can't do what you've described (exchange an access_token intended for one audience, for an id_token intended for a different audience). There are some variants of token exchange which you can do, but none of them would help you in this situation.
Instead, what you should do is define the app roles on the web API. Then, assign the users to the corresponding app role for the web API. When these users sign in to the SPA, and the SPA gets an access token on their behalf to the web API, you'll notice the access token will contain the roles claim, populated with the appropriate values.
Summarizing:
Under App registrations for the web API, define your appRoles in the app manifest (or on the Application object directly, using (for example) Azure AD PowerShell).
Under Enterprise apps for the web API, assign users and/or groups to their corresponding app roles, and choose whether or not app role assignment is required or not*. (Or do so directly on the ServicePrincipal object.)
Under App registrations for the SPA (the Application object), add the web API as a required permission.
*If you choose to require app role assignment for the web API (under Enterprise apps > Properties), the SPA will not be able to get an access token for users who are not assigned to an app role for the web API. If you choose not to require app role assignment , users who are not assigned an app role will be able to sign in to SPA and the SPA will be able to get an access token on their behalf for the web API, but the access token will not contain a roles claim.

Azure Active Directory Consent Framework not kicking in for .NET client application

I have a Web API running in an Azure Web App. It is used from a .NET WinForms client application. In the same Azure Web App, there is also an ASP.NET MVC site.
Users authenticate to the site and the .NET client using Azure AD credentials. This should be multi-tenant. The MVC app works fine multi-tenant, but I have trouble getting the client to run multi-tenant.
My understanding from https://learn.microsoft.com/en-us/azure/active-directory/active-directory-integrating-applications is that the Consent Framework should kick in automatically if OAuth 2.0 is used. I am using code (below) that is very close to the sample at https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-webapi-multitenant-windows-store/.
While I can successfully log in with a user in the tenant where the native app is defined and use the app, I cannot use the app with a user from another tenant. There is no consent asked and I get an AdalException:
AADSTS50001: The application named https://<myurl> was not found in the tenant named <sometenant>.onmicrosoft.com. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
Trace ID: 3<snip>2
Correlation ID: 2<snip>a
Timestamp: 2017-01-05 01:01:10Z
I have added the ID of the native client app to the list of knownClientApplications in the web app's manifest. I am authenticating against the "common" tenant (https://login.microsoftonline.com/common). The third-party tenant user account signing in is a Global Admin in that tenant.
So, I am clearly overlooking something to enable the Consent Framework but I can't find what it is based on the sample...
Relevant native client code below
Uri RedirectUri = new Uri(sRedirectUri);
// AadInstance is the common tenant
AuthenticationContext authContext = new AuthenticationContext(AadInstance);
try
{
PlatformParameters pp = new PlatformParameters(PromptBehavior.Auto);
// Authenticate to Azure AD
Program.WebApiAuthenticationResult = await authContext.AcquireTokenAsync(WebAppIdUri, ClientID, RedirectUri, pp);
return true;
}
catch (AdalException ex)
{
MessageBox.Show(ex.Message, "Log In Not Successful");
}
Thanks for any insight!
I am trying to reproduce this issue however failed. The scenario that native client app consume the web API which both protect by Azure works well when I login the native app with the multiple tenant account. I tested the code sample from here.
And based on the error message, it seems that the resource is not correct, please ensure it is same as the APP ID URI for the web API app you register on Azure. I could get the same error message when I specify an incorrect resource.

How to validate user credentials against custom api

I just create my first Okta application using a dev account.
The app supports saml2.0 to authenticate user.
My goal is to make Okta app as a smal2.0 IdP and having my on-premiesis web app acting as a SP. The flows works great.
As first step to test the flow I created a "user base"(people) in Okta.
Would it be possible to engage from Okta app a custom api (on-premesis) to validate the user credentials (supplied within the Okta built-in login page)?
IOW I'd like to use Okta app simply as saml2.0 IdP, managing the saml2.0 protocol, but I'd like to keep the user base locally.
We do provide SDKs to interact with our API, and you can find them at http://developer.okta.com/docs/sdk/core/api.html.
For instance, the Okta Music Store available at https://github.com/okta/okta-music-store demonstrates how you can authenticate Okta users in an ASP.NET MVC app and automatically provision them into a local database "on the fly" when they sign in.
I hope this helps!

Resources