I created two application instances [Dynamics 365 Finance and Operations] for prod and test environments. I'm now getting the following error.
Unable to get the channel information Detail
Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException:
AADSTS700027: Client assertion contains an invalid signature. [Reason
- The key was not found., Thumbprint of key used by client: '0DEC01638DF6D70A2D57DFE338ABFC3D6BD45458', Please visit
'https://developer.microsoft.com/en-us/graph/graph-explorer' and query
for
'https://graph.microsoft.com/beta/applications/00000015-0000-0000-c000-000000000000'
to see configured keys] Trace ID: afa96f28-9dbe-48cb-a569-431f637b1a00
Correlation ID: 8981ef7c-9bd5-427e-bd33-072fc7faca86 Timestamp:
2020-02-05 07:47:17Z ---> System.Net.Http.HttpRequestException:
Response status code does not indicate success: 401
This log is from the test environment and now it started giving this error after I started creating the production environment using this AAD_AppId: 00000015-0000-0000-c000-000000000000. So my question is, Is it possible to use the same AAD_AppId for two applications.
No, you can't.
The Application ID of an AD App is a GUID across all the Azure AD tenant, you can just use the same Displayname of the AD App for your prod and test environments at most. Eevn they have the same Displayname, they will have different Application IDs.
Besides, the 00000015-0000-0000-c000-000000000000 is the Application ID of the Microsoft application Microsoft Dynamics ERP, it will appear in the Enterprise applications in the AAD tenant which used it, they will have different Object id
in different tenant, but they will have the same Application ID.
Related
I have registered APP in Azure Portal and successfully generated credentials in Microsoft Graph API. after outlookmail.init Operation in WSO2 EI, i am getting below ERROR.
ERROR:
{"error":"unauthorized_client","error_description":"AADSTS700016: Application with identifier 'a4935017-80e8-4413-a762-780b32d8f968' was not found in the directory 'e5e67d60-adf4-40b4-883c-351dc2feef4e'. 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 may have sent your authentication request to the wrong tenant.\r\nTrace ID: 4ecb19d5-e66b-40c1-9a15-7237a0d4c801\r\nCorrelation ID: 818ba54d-f5e5-43df-9201-96d71f598b1f\r\nTimestamp: 2021-07-08 10:14:35Z","error_codes":[700016],"timestamp":"2021-07-08 10:14:35Z","trace_id":"4ecb19d5-e66b-40c1-9a15-7237a0d4c801","correlation_id":"818ba54d-f5e5-43df-9201-96d71f598b1f","error_uri":"https://login.microsoftonline.com/error?code=700016"}
CODE:
<outlookmail.init>
<accessToken>{$ctx:accessToken}</accessToken>
<apiUrl>{$ctx:apiUrl}</apiUrl>
<apiVersion>{$ctx:apiVersion}</apiVersion>
<refreshToken>{$ctx:refreshToken}</refreshToken>
<clientSecret>{$ctx:clientSecret}</clientSecret>
<clientId>{$ctx:clientId}</clientId>
<redirectUri>{$ctx:redirectUri}</redirectUri>
<resource>{$ctx:resource}</resource>
<registryPath>{$ctx:registryPath}</registryPath>
<intervalTime>{$ctx:intervalTime}</intervalTime>
</outlookmail.init>
<log level="full"/>
Application in Azure Portal:
I have seen error code in this site which says like below.
This usually occurs when the client application isn't registered in Azure AD or isn't added to the user's Azure AD tenant. The application can prompt the user with instruction for installing the application and adding it to Azure AD
Can anyone please help me to resolve this?
Not sure if it helps, but I had a lot of similar problems with graph / wso2. Here a few things to check.
1.) check that the access/api is created by an administrator
2.) check that the api has "admin consent"
3.) i had to add a "access key" and use that one
4.) check that you use the ConfidentialClientApllication builder if you use JAVA SDK
Beside that there were a few pages that helped me to get it working.
https://blogs.aaddevsup.xyz/2020/04/implement-client-credentials-flow-for-graph-java-client/
https://learn.microsoft.com/en-us/graph/tutorials/java
Regards
Martin
Is there a way to get value of "objectIdentifier" claim for Microsoft account?
Case: I have an app with one form field, email (need's to be Microsoft account). When this email is entered, server (back end) need's to find out value of object identifier (user ID) in common tenant for all Microsoft accounts (section "tid").
Normally, if this was normal tenant in Azure Active Directory I would create Azure AD app and generated client secret for accessing Graph API, directory endpoint. Unfortunately, this is "special" tenant and I don't know is there any API I can call (as application) to get id of user (best option would be GetUserIdByEmail(email)).
I understand this is weird case but life is hard :)
Asking user to login and then retrieving value from token is not an option!
There is no API that I'm aware of where you could query for MS personal accounts' info without logging a user in.
If you think about it, it would be quite an easy source of building a user list for attacks :)
You will need to log them in to get their id, I don't think you can know it in advance.
I am trying to find a way how to programmatically change properties of Enterprise Application (non-catalogue app), specifically Secret Token and Tenant ULR in 'Provisioning' blade, allowing to synchronize user/group objects between AAD and an external app (e.g. SaaS app) that supports it.
My customer has a strict policy to rotate all secrets and keys in Azure in regular intervals, so they want to be able to have an automation runbook that would change that token in the app (it is actually an Azure Databricks instance that supports this sync) as well as in AAD.
I checked whether there was a direct PowerShell support but I couldn’t find a specific cmdlet for this scenario (tried both GA and preview versions of AAD PowerShell 2.0).
I found a good documentation page describing AAD Synchronization API - https://learn.microsoft.com/en-us/graph/api/resources/synchronization-overview?view=graph-rest-beta – however, I am unable to find, how to update the Secret Token property.
Ideally, I would like to see a code sample of a REST call on how change that specific property using Synchronization API. A PowerShell example would be even better. Any help is much appreciated. Thanks.
Here's how to do it for non-gallery SCIM apps:
PUT https://graph.microsoft.com/beta/servicePrincipals/99abefe8-3ad8-488f-b14f-df209cbc1ab3/synchronization/secrets
{
value: [
{ key: "BaseAddress", value: "xxxxxxxxxxxxxxxxxxxxx" },
{ key: "SecretToken", value: "xxxxxxxxxxxxxxxxxxxxx" }
]
}
Replace the GUID after servicePrincipals with your real servicePrincipal object ID.
For apps that aren't non-gallery SCIM apps, the credential names required can be discovered in the metadata -> configurationFields part of the synchronizationTemplate object:
https://learn.microsoft.com/en-us/graph/api/resources/synchronization-synchronizationtemplate?view=graph-rest-beta
I am experiencing an issue where a set of custom policies that upload without issue to one tenant (development tenant), fail to upload to another (production tenant). The policies function correctly on the (working) development tenant.
I upload the files in the following order:
TrustFrameworkBase.xml uploads OK
TrustFrameworkExtensions.xml uploads OK
SignUpOrSignin.xml fails with above error
ProfileEdit.xml fails with above error
PasswordReset.xml uploads OK
The only clue I have is that if I query the extension claims in the B2C app for the failing tenant, it only shows 2 out of 8. If I run the same query against the working tenant, it shows all 8. I am doing this querying using this example app: https://github.com/AzureADQuickStarts/B2C-GraphAPI-DotNet.
As far as I can tell, the two tenants are configured the same, and I have checked the various IDs etc are configured correctly. But it is always possible I have missed something!
Can anyone help?
The xml files: https://1drv.ms/f/s!ApxUZQaL9hp0h1ACYgWzgzsGwCOc
More info
I can actually run the policies that upload with an error. But when I try to create an user account via running the policy I get a message saying "Unable to validate the information provided." at the top of the page, inside the <div> with the id claimVerificationServerError. This may tie-up with the missing extension claims in the B2C app. So it looks like the problem is with creating the extension claims. But the same policy uploads and works on another tenant. How could the extension claims be valid on one tenant, but not on another?
In your base policy, there is the following claim of dateOfBirth:
<ClaimType Id="extension_DateOfBirth">
<DisplayName>Date of Birth</DisplayName>
<DataType>date</DataType>
<UserHelpText>Date of birth</UserHelpText>
<UserInputType>DateTimeDropdown</UserInputType>
<PredicateValidationReference Id="DateOfBirthDateRange" />
</ClaimType>
Since this claim starts with "extension_" and it is used in a technical profile with "AAD-" as prefix, it will be automatically created as an extension attribute in AAD during the policy uploading. However, the DataType "date" is not supported (only DateTime is supported) in AAD. This is causing policy uploading failure.
Regarding how to map "date" claim in B2C policy to AAD "DateTime" attribute, I will reply back to this thread after more investigation on these policies is done.
Edit: I was trying to find this doc: https://msdn.microsoft.com/Library/Azure/Ad/Graph/api/entity-and-complex-type-reference#extensionproperty-entity when I first replied but could not find it. Thanks Mat for sharing. Hope this link is helpful for solving issues related to datatype of extension attributes in AAD.
Extension attributes need to be created at a per tenant basis. So if your policy requires extension attributes, you need to create them explicitly.
Our application (referred to as "XYZ_App" below) is a multi-tenant SaaS application. We are in the process of making it available for Microsoft AppSource as a multi-tenanted "Web app / API" (referred to as "AppSourceXYZ_App" below).
We started our OpenID Connect implementation with endpoints pointing to “common” as per stated in the documentation when multi-tenancy is desired/required.
In XYZ_App, we added information in the system to know what AAD instance each XYZ_App tenant is associated with (using the GUID Microsoft assigned to this AAD instance, we are NOT using the "rename-safe.onmicrosoft.com" representation).
When using the “common” endpoints, we had to manually validate the issuer from the JWT to make sure it was the expected one: a user could access XYZ_App requesting access to XYZ_App’s tenant associated with contoso.onmicrosoft.com, get directed to “login.microsoftonline.com/common” to authenticate and then decide to authenticate with a user from another AAD instance (referred to as "anotherAADInstance.onmicrosoft.com" below). In this scenario, even though a user could successfully authenticate on anotherAADInstance.onmicrosoft.com, XYZ_App’s redirect URI must make sure the JWT issuer is the one from contoso.onmicrosoft.com. I’ll refer to this setup as Scenario_1.
With that scenario in mind, we thought about NOT using “common” and customize the requests going to login.microsoftonline.com on the fly; attempting to “jail” requests to be forced to authenticate against a specific AAD instance. We would still need to perform our validation in the redirect URI to make sure the issuer is the appropriate one, but we thought this approach might make our lives easier. I’ll refer to this setup as Scenario_2.
Do you envision Scenario_2 is viable in the long run or is it too short-sighted ? Based on my current knowledge of OpenID Connect, one limitation I can see with Scenario_2 is that it would become problematic to support “broker accounts” into our app.
Explanation of “broker accounts”: in our industry, some external users are allowed access to the system. Let’s say I have a company called “BrokerCo” (with their own brokerco.onmicrosoft.com AAD instance) who has 2 employees: Broker1 and Broker2. BOTH anotherAADInstance and contoso hired Broker1 and Broker2 to get broker services to perform tasks in XYZ_App; requiring XYZApp to grant them access. What is the ideal way for authentication from an OpenID Connect standpoint ? If XYZ_App were to use “login.microsoftonline.com/common” for authentication (like in Scenario_1; as opposed to “jailed” access like in Scenario_2), Broker1 and Broker2 could authenticate with brokerco.onmicrosoft.com (no AAD "External users" for anotherAADInstance nor contoso), but they would then get to redirect URI with an issuer that is different than what XYZ_App’s anotherAADInstance and contoso tenants are configured for... I feel like I’m back to square 1...
Do you have suggestions or pointers to solve this issue ?
Background context:
While playing with OpenID Connect issuers, I got the following error message:
AADSTS50020: User account 'testuser#anotherAADInstance.onmicrosoft.com' from identity provider 'https://sts.windows.net/XXXXXXXX-fake-GUID-9bZZ-XXXXxxxxXXXX/' does not exist in tenant 'XYZ Publisher' and cannot access the application 'YYYYYYYY-fake0-GUID-YYYYyyyyYYYY' in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account.
Thanks in advance !
Your question has multiple layers, trying to address most of them:
AppSource is about trial experiences for new users: this mean that any corporate account around the globe can potentially be an user of your SaaS application - or at least to the trial experience of your application, therefore the first thing you need to think when integrating with AppSource is how easy it has to be for a potential user to experience your app for the first time.
With that in mind, AppSource recommends that the trial of application is build on such a way that allows any user from any organization to sign-in, and therefore a multi-tenant approach for your application is the recommended setup for any application.
The single-tenant approach requires more control on your side, and for a trial experience - it means that the user cannot try your application right away because the operation you have to do on your single-tenant application is to add the user to an Azure Active Directory tenant as a guest user. This guest account will need then to wait receiving an email to accept the invitation to join to this tenant you are adding the user to then sign-in to your application.
Therefore your scenario 1 is the best scenario thinking on a trial experience in general, and also in general require less management (as you'd not need to create/ manage each individual account that needs to access your application as guest users of your Azure AD instance).
However some concerns you listed - that this scenario bringing are valid: Because you are accepting the common endpoint, you are saying basically that any user can sign-in to any tenant to your application, and this may not be desirable. In addition, the scenario you listed that a user can generate a token for any application is also valid, however, you can add additional checks to make this more secure and that any token generated by another authentication is blocked:
You can validate the 'audience' claim to guarantee that the token was issued to your application
You can eventually check the 'tid'/'iss' claims against of a list of tenant Ids in your database to see if that the user's organization is a valid organization in your application -- this would be valid for non-trial users/ organizations.
More information in this article.
About scenario '2' and broker accounts:
This scenario could be interpreted in two different ways:
Broker accounts are guest accounts of a customers' Azure AD tenant
Broker accounts are third party accounts but are not actually added as a user of anotherAADInstance or contoso AD
If your case is '1' then you're right: if your application needs to authenticate guest users that belong to another Azure AD tenant, then common endpoint could not be used directly.
If your case is '2' then what you'd need to do is to continue using the common endpoint and somewhat after the user is authenticated ask them to choose the company. I am describing this on generic terms without fully understanding this scenario. Perhaps this is not simple as you want the remote company to control this and not the user - so some additional complexities may need to be handled here.
A note is that if your scenario is scenario 1. - in theory - you can still use an hybrid approach, where you'd ask user to type the username inside the application and the company that they want to sign-in, then check if you need to validate the user against common or tenant-id endpoint, preparing the request and then sending a login_hint argument when authenticating. More information here