Creation of user fails after deletion of user with same signInName - azure

I can successfully create users in an Azure AD B2C tenant through the graph api. I can delete the user as well.
When I try to insert a user with the same signInName again, the request fails with this message:
"odata.error": {
"code": "Request_BadRequest",
"message": {
"lang": "en",
"value": "Another object with the same value for property signInNames already exists."
},
"date": "2016-10-11T15:53:58",
"requestId": "911fcff7-f2f0-4126-aa1e-3c03a757ac0d",
"values": [
{
"item": "PropertyName",
"value": "signInNames"
},
{
"item": "PropertyErrorCode",
"value": "ObjectConflict"
}
]
}
After I wait some minutes (5-20?) I can successfully insert the user with the original signInName.
After successful deletion the user is not visible when I list all users.
Renaming the user before deletion works fine but I can still not create the user with the original signInName.
Is it possible to speed this up?

When you created the service-principal, you also created an application.
use this command to also remove the application:
remove-azurerdadapplication -objectId [key]

I have encountered the same issue in Azure AD.
I Don't think there is anything you can do in your code to speed this up. (Azure AD PMs can answer the question of: what is the real SLA for a delete operation to completely propagate through the system)
I guess all you can do is to consider this error as if the user is actually there when you get this error (Although you can see it in the list).
Not sure about your exact scenario, but this was a really edge case for us.
Another workaround that we were thinking about in our case was: not to delete a user at all and just remove their roles if there is a chance that the user with same ID is needed later on
Because when the user is deleted the ObjectID or UserKey changes and we had references in our system to that ObjectId and that object ID will not exist in Azure AD anymore so we decided to keep the users in most cases unless we really had to delete them.

Related

adal:tokenRenewFailure, code: invalid_resource|AADSTS500011

I'm trying to build a simple Teams tab app that lists the members of a team. I've used the Teams Toolkit for VS Code to generate the boilerplate. Running the app using F5 works fine. So far, so good.
Next I'm trying to read the team members from Graph. I've read about RSC (resource-specific consent) which seems to be exactly what I need. Because I want to prevent the app from opening any permission popups or login popups (other than the one appearing during the installation).
So I've followed the guide https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent and I've also made the check. Works fine.
However, as soon as I'm running the code locally (using F5), I'm getting this error:
AUTHMSAL: Event: adal:tokenRenewFailure, code: invalid_resource|AADSTS500011: The resource principal named api://localhost:53000/MY-CLIENT-ID-UUID was not found in the tenant named MYTESTTENANT. 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.
I've double checked: the tenant does exist (and there's only this one). The app id is also correct, it resembles the one I've added using the "App registration". I've also added a "Client secret", however I'm not exactly sure where to add it to my code. This is probably the root cause of my problem.
The relevant parts of my code are:
// manifest.template.json
{
...
"webApplicationInfo": {
"id": "MY-CLIENT-ID-UUID",
"resource": "api://localhost:53000/MY-CLIENT-ID-UUID"
},
"authorization": {
"permissions": {
"resourceSpecific": [
{
"name": "TeamSettings.Read.Group",
"type": "Application"
},
{
"name": "TeamMember.Read.Group",
"type": "Application"
},
// ... (I've added *all* other permissions, too, just for testing...)
]
}
}
}
// Tab.tsx
// ...
// I've read on NPM that useTeamsFx() is deprecated and switched to useTeamsUserCredential()
const all = useTeamsUserCredential({
clientId: "MY-CLIENT-ID-UUID",
initiateLoginEndpoint: "fooBarInitiateLoginEndpoint",
// ...don't I have to add my clientSecret somewhere?
});
// Welcome.tsx
// ...
const { loading, error, data, reload } = useGraphWithCredential(
async (graph, credential, scope) => {
await graph.api(`/teams/MY-GROUP-ID/members`).get() // leads to the error
},
{
scope: [
"TeamMember.Read.Group"
],
credential
}
)
I've also tried to follow the AddSSO guide, but it led to permission popups which I want to prevent. Plus it added a lot of AAD specific stuff (like aad.template.json), which I don't need, because RSC suffices in my case (...right?).
Also, my app doesn't need SSO (...right?) because it only lists the members of the team and it runs inside Teams only...
EDIT
I've also tried new TeamsFx(IdentityType.App) instead of useTeamsUserCredential() (because RSC permissions have "type": "Application" in the manifest.template.json), however this ended up in an error:
Uncaught ErrorWithCode.IdentityTypeNotSupported: Application identity is not supported in TeamsFx
Somebody else may be able to provide you a full Teams example, but the main error in your case is this one:
AUTHMSAL: Event: adal:tokenRenewFailure, code: invalid_resource|AADSTS500011: The resource principal named api://localhost:53000/MY-CLIENT-ID-UUID was not found in the tenant named MYTESTTENANT. 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.
The reason for this is here:
"webApplicationInfo": {
"id": "MY-CLIENT-ID-UUID",
"resource": "api://localhost:53000/MY-CLIENT-ID-UUID"
},
"api://localhost:53000/MY-CLIENT-ID-UUID" is not a valid resource identifier. Please note that this is not the API url, but rather its identifier. Please look for the App Id URI in your application registration in Azure Portal.
The correct value is most likely api://<your-client-id>, but you need to set it first.
See also Does the resource URL in webApplicationInfo need to contain the Microsoft Teams App ID?
https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/<your-client-id>/

Check if users deleted in clients Azure AD

I am integrating Login with Azure AD for one of my clients on my website. I am only targeting one specific group in their organisation, and not everybody in the entire organisation.
This new feature has 2 requirements:
We need to create an account for people logging in via their email using our clients Azure AD.
We need to run a CRON job daily to check if anybody has been removed in their AD (due to them leaving the company), so we also need to remove their profile in our application.
For number 1, I think it's sufficient to call the /authorization, /token and /userinfo endpoints. Is this correct?
But for number 2, I am having issues to see how this is possible.
When browsing the graph explorer (https://developer.microsoft.com/en-us/graph/graph-explorer) I can find the following 2 API methods:
GET all users in the organization /users ---> But i am unsure whether this returns all the users in their AD, or only the ones applicable for my application?
GET direct members of a group with count /groups/<id</members ---> Is this the one I am looking for when they are assigned into a specific group?
I've also found this SO link : https://stackoverflow.com/a/64553305 which talks about saving the access token and refresh token. Is it possible if I save these two to fetch the userinfo at any point in time? This way I could possibly query all the created accounts each day and if one of them returns a status deleted, or empty I know the account no longer exists? Or is this not an option?
Thanks in advance!
UPDATE:
I noticed that my client granted me the User.Read and User.Read.All graph permissions.
But i'm not certain how to call this API? When calling this API in Postman :
https://graph.microsoft.com/v1.0/users/123-this-is-the-id
I am getting the following response:
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token is empty.",
"innerError": {
"date": "2021-10-07T12:59:05",
"request-id": "...",
"client-request-id": "..."
}
}
}

How to grant access to read/write files on a sharepoint site via OAuth2

I am having trouble figuring out how to give an application read/write access to a sharepoint site.
Here's what I've done:
I made a sharepoint site
I created a microsoft azure application and authenticated users using OAuth2
I set delegated permissions on the app control panel to include Files.ReadWrite.All
I created a user who has read/write permissions to the sharepoint site and authenticated him with the app.
I have a program (in PHP) which has valid access_token and refresh_token, but when I try to upload files, I get a 403 error.
Client error: `PUT https://graph.microsoft.com/v1.0/drives/b!XxxxxxxxxxxxxxxxB/items/root:/StationMD%20Addl%20Enrollees%2020200508.xlsx:/content` resulted in a `403 Forbidden` response:
{
"error": {
"code": "accessDenied",
"message": "Access denied",
"innerError": {
Oddly enough, I was able to do this as the user who created the site, but not as a dummy user (who also has permission to read and write files)
So...
The problem seems to be app permissions. Is there a way to set application permissions for just that sharepoint site, or is Files.ReadWrite.All my only option? Can I use delegated permissions for a user who is not currently logged in, but did authenticate via OAuth2?
Some more information 5/16/20
I have two users. One is my regular account which I used to create the Sharepoint Site. The other is a "service account" used to upload files. Both users are able to edit/upload/delete files using the GUI. However, when using the API, the service user can't upload files, while the regular user can. I made sure that both users were members of the site. Using the Graph Explorer, I am able to see the drive.
https://graph.microsoft.com/v1.0/drives/b!XXXXxxxxx
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#drives/$entity",
"createdDateTime": "2020-04-26T11:19:17Z",
"description": "",
"id": "b!XXXXXxxxxx",
"lastModifiedDateTime": "2020-05-16T11:56:23Z",
"name": "Documents",
"webUrl": "https://xxxxxxx.sharepoint.com/sites/sftp/Shared%20Documents",
"driveType": "documentLibrary",
"createdBy": {
"user": {
"displayName": "System Account"
}
},
"owner": {
"group": {
"email": "xxxx#xxxxxx.onmicrosoft.com",
"id": "xxxxx-xx-xxxx-xxxx-xxxxxxxx",
"displayName": "sftp Owners"
}
},
"quota": {
"deleted": 2812850,
"remaining": 27487773843447,
"state": "normal",
"total": 27487790694400,
"used": 8848121
}
}
It's been quite a while since I worked with SharePoint, but I'll try to answer for the Azure AD related questions.
Oddly enough, I was able to do this as the user who created the site, but not as a dummy user (who also has permission to read and write files)
This is pretty odd. I would expect the call to work with the permissions the app has :\
Is there a way to set application permissions for just that sharepoint site, or is Files.ReadWrite.All my only option?
This one I am not sure about.
You can either give the app the delegated permission Files.ReadWrite.All which allows you to access/modify any file the user can, or you can give the application permission Files.ReadWrite.All which allows the app to access/modify any file in any site collection.
Can I use delegated permissions for a user who is not currently logged in, but did authenticate via OAuth2?
Short answer, yes.
If they authenticated at least once to your app, you got a refresh token for that user when they did.
Store that refresh token securely, and use it to get a new access token when needed.
Do note a couple things:
The refresh token itself will expire after some time (maybe 2 weeks?)
When you get a new token with that refresh token, you also get a new refresh token
Token refresh can fail due to some factors, your app should be ready for this
The user will have to authenticate again to provide a new refresh token
Based on my knowledge:
Can't limit to specific site in app permission level(limit in logic if need).
Use Application permission if want to skip user to log in.
Use permission in Microsoft Graph to access data in SharePoint if want to use graph api.

Azure course that tries to use Azure Cloud Shell fails with "RequestDisallowedByPolicy" using free account

I was asked by Azure Support to post this question, just to see if anyone had a useful opinion.
I am stepping through MS Azure training courses. I created the usual free account to go through these. I've gone through a few dozen of them, and am now at this one:
https://learn.microsoft.com/en-us/learn/modules/secure-and-isolate-with-nsg-and-service-endpoints/3-exercise-network-security-groups?source=learn
This attempts to use the Azure PowerShell service. I had some trouble getting to the PowerShell page. It appears that if I'm not already logged into the portal, it goes into a semi-infinite loop, trying to get to the shell page, then trying to login, then the shell page, and finally it gives up and says "We couldn't sign you in. Please try again.".
However, I was able to work around this. If in a separate tab, I log into the Azure Portal, and then go back and follow the link to Azure Cloud Shell, it passes the login gate and sends me to the page where I choose Bash or PowerShell. The course specifies using Bash. When I select that, it then asks me to create a Storage object. When I confirm that, it gives me the following error (subscription id elided):
{
"error": {
"code": "RequestDisallowedByPolicy",
"target": "cs733f82532facdx4f04x95b",
"message": "Resource 'cs733f82532facdx4f04x95b' was disallowed by policy. Policy identifiers: '[{\"policyAssignment\":{\"name\":\"Enforce tag on resource\",\"id\":\"/subscriptions/xxxxx/providers/Microsoft.Authorization/policyAssignments/740514d625684aad84ef8ca0\"},\"policyDefinition\":{\"name\":\"Enforce tag on resource\",\"id\":\"/subscriptions/xxxxx/providers/Microsoft.Authorization/policyDefinitions/be3862a6-ca1e-40b0-a024-0c0c7d1e8b3e\"}}]'.",
"additionalInfo": [
{
"type": "PolicyViolation",
"info": {
"policyDefinitionDisplayName": "Enforce tag on resource",
"evaluationDetails": {
"evaluatedExpressions": [
{
"result": "True",
"expressionKind": "Field",
"expression": "tags[Department]",
"path": "tags[Department]",
"targetValue": "false",
"operator": "Exists"
}
]
},
"policyDefinitionId": "/subscriptions/xxxxx/providers/Microsoft.Authorization/policyDefinitions/be3862a6-ca1e-40b0-a024-0c0c7d1e8b3e",
"policyDefinitionName": "be3862a6-ca1e-40b0-a024-0c0c7d1e8b3e",
"policyDefinitionEffect": "deny",
"policyAssignmentId": "/subscriptions/xxxxx/providers/Microsoft.Authorization/policyAssignments/740514d625684aad84ef8ca0",
"policyAssignmentName": "740514d625684aad84ef8ca0",
"policyAssignmentDisplayName": "Enforce tag on resource",
"policyAssignmentScope": "/subscriptions/xxxxx",
"policyAssignmentParameters": {
"tagName": {
"value": "Department"
}
}
}
}
]
}
}
I think the simple conclusion from this is that my free account doesn't have enough rights to do what is needed here. The documentation I've read seems to imply that I have to get additional rights on the account in order to do this. However, I'm just using a free account that I created to go through the Azure training courses. It doesn't really make sense to ask me to do this. I've seen other Azure courses create a temporary sandbox supposedly because they have particular objects pre-created in the sandbox, but I'm also thinking that the sandbox has particular permissions that are not available in the free account. It seems to me that the only reasonable fix for this problem is for that course to be refactored to use a temporary sandbox with the correct permissions.
I'm just looking for any opinions on this, and confirmations that this is what should be done.
It doesn't look like you are creating resource, cloudshell storage, on your free subscription. Except if you added to a Work/Corporate tenant.
From the information you provide, subscription you are trying to use has a policy to enforce tags Department, mean any resource created should have a tag with Department information.

Azure AD App registration user roles not reflecting

I have added an app registration with custom user roles through the manifest
I have successfully protected an API endpoint by way of the [authorize] atribute and roles.
I have now changed the names of the roles in AD but when I try to access the API endpoint I can see in the access token that the roles have not changed.
How long does it take for roles to change for a user? Do I need to do something else other than just change the names of the roles? Force a cache refresh somewhere? What am I missing?
I am using a private browser window to eliminate any stale cookie noise
I can see in the access token that the roles have not changed.
Shouldn't the user role be reflected in Id token?
The decoded Id token.
How long does it take for roles to change for a user? Do I need to do
something else other than just change the names of the roles?
We should change the value of the role, not the displayName. And it will take effect immediately.
"allowedMemberTypes": [
"User"
],
"description": "Creators can create Surveys",
"displayName": "SurveyCreator2",
"id": "1b4f816e-5eaf-48b9-8613-7923830595ad",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "SurveyCreatorValue3"
}
I changed the role value from SurveyCreatorValue3 to SurveyCreatorValue4. We can see the update in the Id token.

Resources