Change Azure AD B2C User Password with Graph API - oauth-2.0

I'm trying to use the Sample Graph API app to change a user's password but I'm getting:
Error Calling the Graph API Response:
{
"odata.error": {
"code": "Authorization_RequestDenied",
"message": {
"lang": "en",
"value": "Insufficient privileges to complete the operation."
}
}
}
Graph API Request:
PATCH /mytenant.onmicrosoft.com/users/some-guid?api-version=1.6 HTTP/1.1
client-request-id: ffd564d3-d716-480f-a66c-07b02b0e32ab
date-time-utc: 2017.08.10 03:04 PM
JSON File
{
"passwordProfile": {
"password": "Somepassword1$",
"forceChangePasswordNextLogin": false
}
}
I've tested updating the user's displayName and that works fine.
{
"displayName": "Joe Consumer"
}
AD Application Permissions
I've configured my app permissions as described here.

Check out this article. Seems like it has the same symptoms.
Solution 1:
If you are receiving this error when you call the API that includes only read permissions, you have to set permissions in Azure Management Portal.
Go to Azure Management Portal and click Active Directory.
Select your custom AD directory.
Click Applications and select your Application.
Click CONFIGURE and scroll down to the section 'Permissions to other applications'.
Provide required Application Permissions and Delegated Permissions for Windows Azure Active Directory.
Finally save the changes.
Solution 2:
If you are receiving this error when you call the API that includes delete or reset password operations, that is because those operations require the Admin role of Company Administrator. As of now, you can only add this role via the Azure AD Powershell module.
Find the service principal using Get-MsolServicePrincipal –AppPrincipalId
Get-MsolServicePrincipal | ft DisplayName, AppPrincipalId -AutoSize
Use Add-MsolRoleMember to add it to Company Administrator role
$clientIdApp = 'your-app-id'
$webApp = Get-MsolServicePrincipal –AppPrincipalId $clientIdApp
Add-MsolRoleMember -RoleName "Company Administrator" -RoleMemberType ServicePrincipal -RoleMemberObjectId $webApp.ObjectId
To connect to your B2C tenant via PowerShell you will need a local admin account. This blog post should help with that, see "The Solution" section.

Try below settings, works for me.
Used the below JSON
{
"accountEnabled": true,
"signInNames": [
{
"type": "emailAddress",
"value": "kart.kala1#test.com"
}
],
"creationType": "LocalAccount",
"displayName": "Joe Consumer",
"mailNickname": "joec",
"passwordProfile": {
"password": "P#$$word!",
"forceChangePasswordNextLogin": false
},
"passwordPolicies": "DisablePasswordExpiration",
"givenName": "Joe",
}
Also make sure you assign the application the user account, administrator role which will allow it to delete users link here

Related

Where to find TemplateId while creating custom directory role MS Graph

I want to create custom directory role with specific permissions like:
microsoft.directory/users/create
microsoft.directory/users/delete
microsoft.directory/groups/create
microsoft.directory/groups/delete
microsoft.directory/applications/create
microsoft.directory/applications/delete
microsoft.directory/serviceprincipals/create
microsoft.directory/serviceprincipals/delete
I found how to automate this from MS graph:
POST https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions
Body
{
"description": "Can manage basic aspects of application registrations.",
"displayName": "Application Support Administrator",
"isEnabled": true,
"templateId": "<GUID>",
"rolePermissions": [
{
"allowedResourceActions": [
microsoft.directory/users/create
microsoft.directory/users/delete microsoft.directory/groups/create
microsoft.directory/groups/delete
microsoft.directory/applications/create
microsoft.directory/applications/delete
microsoft.directory/serviceprincipals/create
microsoft.directory/serviceprincipals/delete
]
}
]
}
What is template Id and how to get the value of this?
TIA
Note that, "templateId": "<GUID>" is an optional parameter and you can include it while creating multiple custom directory roles with common parameters.
To get the value of "templateId", you can create one GUID using this PowerShell command: (New-Guid).Guid
I tried to reproduce the same in my environment via Graph Explorer and got below results:
I ran the same query as you and created custom directory role from MS Graph like below:
POST https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions
{
"description": "Can manage basic aspects of application registrations.",
"displayName": "Application Support Administrator",
"isEnabled": true,
"templateId": "38837bf2-39d8-4c14-89f3-3e9c5e6c9b23", //GUID created from PowerShell
"rolePermissions": [
{
"allowedResourceActions": [
"microsoft.directory/users/create",
"microsoft.directory/users/delete",
"microsoft.directory/groups/create",
"microsoft.directory/groups/delete",
"microsoft.directory/applications/create",
"microsoft.directory/applications/delete",
"microsoft.directory/serviceprincipals/create",
"microsoft.directory/serviceprincipals/delete"
]
}
]
}
Response:
When I checked the same in Portal, I am able to find the new custom directory role like below:
To assign this role to user via Graph API, you can make use of below query:
POST https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments
{
"principalId":"<GUID OF USER>",
"roleDefinitionId":"<GUID OF ROLE DEFINITION>",
"directoryScopeId":"/<GUID OF APPLICATION REGISTRATION(ObjectID)>"
}
Response:
When I checked the same in Portal, role assigned to user successfully like below:

Create a New User For Federated Account in B2C

I am failing to add an OpenId account to B2C using Microsoft Graph. What needs to be done to do an add operation?
B2C Setup as TestB2C
In Azure B2C the OpenID Connect (to my companies Azure AD) is setup as an Identity Provider.
For this example, take the blurred out B2C above to be TestB2C.onmicorosoft.com and the target openID is "Corporate AD".
Graph Call To Insert User into B2C
{
"accountEnabled": true,
"displayName": "OmegaMan",
"mailNickname": "OmegaM",
"identities": [
{
"signInType": "userName",
"issuer": "TestB2C.onmicrosoft.com",
"issuerAssignedId": "OmegaMan#Corporate.com"
},
{
"signInType": "emailAddress",
"issuer": "TestB2C.onmicrosoft.com",
"issuerAssignedId": "OmegaMan#Corporate.com"
},
{
"signInType": "federated",
"issuer": "Corporate.com",
"issuerAssignedId": "6ab...34"
}
],
"passwordProfile" : {
"forceChangePasswordNextSignIn": false
}
}
The issuerAssignedId is from the settings placed in the Identity Providers section for the OpenId Connect. When I attempt to insert said user, I get this current error:
...
"error": {
"code": "Request_BadRequest",
"message": "A password must be specified to create a new user.",
...
Which for a federated user does not make sense. Note, that in a different add operation for an "email user", this process works; with different settings. What is missing to then add a federated user?
For a federated user, "accountEnabled" is false.
I was able to circumvent the user "Sign-Up" after user insertion. The issue turned out to be, that to have proper federation occur, the proper values need to be in place.
"identities": [
{
"signInType": "federated",
"issuer": "https://login.microsoftonline.com/XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX/v2.0",
"issuerAssignedId": "YYYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY"
What was happening was that I was using "issuer": "myDomain.com" which was not resolving correctly to do a login; to which the user then had to "SignUp" via the federated IP and ended up with two logins.
By changing issuer from a DNS readable name, to the Microsoft login url with my AD directories' ID (the number provided when switching domain in Azure, XXXX-XXX ... btw) and also a proper issuerAssignedId, found from the originating AD issuer, it worked and the user was added.

unable to get given_name and family_name from azure v2 token endpoint

In the manifest of my application registration I've configured to retrieve the given_name and family_name claims (through the UI, the resulting manifest looks like this):
"idToken": [
{
"name": "family_name",
"source": "user",
"essential": false,
"additionalProperties": []
},
{
"name": "given_name",
"source": "user",
"essential": false,
"additionalProperties": []
}
],
During the redirect I add the profile scope along with the given_name and family_name scopes, which results in the following error.
Message contains error: 'invalid_client', error_description: 'AADSTS650053: The application 'REDACTED' asked for scope 'given_name' that doesn't exist on the resource '00000003-0000-0000-c000-000000000000'. Contact the app vendor.
Any ideas? As I understand that is what is required to configure these optional claims on the v2.0 endpoint as described here: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-optional-claims#v20-specific-optional-claims-set
You should only use the profile 'scope', which should result in you receiving the given_name and family_name 'claims'. That's standard behaviour for an Authorization Server, which will then either:
Return the name details directly in the id token
Or allow you to send an access token to the user info endpoint to get the name details
However, Azure v2 is very Microsoft specific, and user info lookup can be painful and involve sending a separate type of token to the Graph user info endpoint. Hopefully you won't have to deal with that and you will get the name details directly in the id token.
I had a scenario where my API (which only received an access token) needed to get user info, and I solved it via steps 14 - 18 of this write up, but it's a convoluted solution.
Once you configure optional claims for your application through the UI or application manifest. you need to provide profile Delegated permissions for the application.

MS Graph API, Application Type, Admin Consented, Permission "Contacts.ReadWrite" results in Access Denied for any user other than Admin user

Trying to use MS Graph API from an OAuth 2.0 HTTP client authenticated against an Azure App Registration to list and create contact folders and contacts for any user, with an O365 license, in the same tenant. The Graph API calls, from Postman, return valid JSON results only when the target user is the Azure Global Administrator user that granted the MS Graph API permission's Admin consent for the entire Azure tenant. Trying to access the contacts or contact folders of any other tenant user results in an Access Denied JSON error response.
According to MS documentation, the Azure App Registration's, MS Graph API, Admin Consented, Application Type permission Contacts.ReadWrite should permit access to all users contact folders and contacts.
However, it only works to get the contact folders and contacts of the Admin user that Admin Consented the permission. The Admin Consented, Application Type permission is behaving like a non-Admin Consented, Delegated Type permission.
Shouldn't an App Registration with Admin Consented, Application Type Contacts permission allow access to all tenant user's contacts run without the need for each end user to consent access?
Is this a bug or expected behavior for accessing contacts?
Why is there no "All" constraint for the Contacts Read Write permission?
For permissions that do not offer an "All" constraint element on the permission name, does the App Registration ignore the Application Type Admin Consent and default to the user who consented to the permission, running as that user instead? Doesn't that go against the point of having Admin Consent and Application Type permissions?
Do we need to have each user delegate Contact Folder and Contacts access to the Admin user?
1) Created an Azure App Registration
2) Granted Microsoft Graph API, Application Type, permissions to that Azure App Registration for:
https://graph.microsoft.com/Group.ReadWrite.All https://graph.microsoft.com/Directory.Read.All https://graph.microsoft.com/Contacts.ReadWrite
3) Granted Microsoft Graph API, Delegated Type, permissions to that Azure App Registration for:
offline_access
4) Configured Postman OAuth 2.0 access token with scope:
offline_access https://graph.microsoft.com/Group.ReadWrite.All https://graph.microsoft.com/Directory.Read.All https://graph.microsoft.com/Contacts.ReadWrite
Data has been [OMITTED] from the example below.
Get the contacts of the Azure Global Administrator user (example: admin_user#fake.com) that granted Admin Consent to the MS Graph API Application Type Permissions:
REQUEST:
https://graph.microsoft.com/v1.0/users/admin_user#fake.com/contacts
RESPONSE:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('admin_user%40fake.com')/contacts",
"value": [
{
"#odata.etag": "W/\"[OMITTED]\"",
"id": "[OMITTED]",
"createdDateTime": "2019-10-25T17:11:06Z",
"lastModifiedDateTime": "2019-10-30T13:11:13Z",
"changeKey": "[OMITTED]",
"categories": [],
"parentFolderId": "[OMITTED]",
"birthday": null,
"fileAs": "test, Test",
"displayName": "Test test",
"givenName": "Test",
"initials": null,
"middleName": null,
"nickName": null,
"surname": "test",
"title": null,
"yomiGivenName": null,
"yomiSurname": null,
"yomiCompanyName": null,
"generation": null,
"imAddresses": [],
"jobTitle": null,
"companyName": null,
"department": null,
"officeLocation": null,
"profession": null,
"businessHomePage": null,
"assistantName": null,
"manager": null,
"homePhones": [
"666-666-6666"
],
"mobilePhone": "555-555-5555",
"businessPhones": [
"777-777-7777"
],
"spouseName": null,
"personalNotes": "Test",
"children": [],
"emailAddresses": [],
"homeAddress": {},
"businessAddress": {},
"otherAddress": {}
}
]
}
Try to get the contacts of any other user with an O365 License (example: other_user#fake.com):
REQUEST:
https://graph.microsoft.com/v1.0/users/other_user#fake.com/contacts
RESPONSE:
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"request-id": "[OMITTED]",
"date": "2019-11-04T16:40:58"
}
}
}
Get the contact folders of the Azure Global Administrator user (example: admin_user#fake.com) that granted Admin Consent to the MS Graph API Application Type Permissions:
REQUEST:
https://graph.microsoft.com/v1.0/users/admin_user#fake.com/contactfolders
RESPONSE:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('admin_user%40fake.com')/contactFolders",
"value": [
{
"id": "[OMITTED]",
"parentFolderId": "[OMITTED]",
"displayName": "Test Contacts Folder"
}
]
}
Try to get the contact folders of any other user with an O365 License (example: other_user#fake.com):
REQUEST:
https://graph.microsoft.com/v1.0/users/other_user#fake.com/contactfolders
RESPONSE:
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"request-id": "[OMITTED]",
"date": "2019-11-04T16:49:42"
}
}
}
Current perms on App Registration
From the documentation:
There are two scenarios where an app can get contacts in another user's contact folder:
If the app has application permissions, or,
If the app has the appropriate delegated permissions from one user, and another user has shared a contact folder with that user, or, has given delegated access to that user. See details and an example.
In other words, when using Delegated scopes a user may only access their own Contacts or Contacts explicitly shared with them.
If you want to access any user's contacts, you need to use the Contacts.Read or Contacts.ReadWrite Application scope.
In general, Exchange-based resources do not use the .All conventions. They rely on the scope type (Application vs Delegated) to determine if the application can see all user or only the authenticated user's resources.

Using the Microsoft Team Beta API, provisioning Teams

I have been trying to use the Graph API, beta version, and am able to create an office 365 group , but so far no luck with adding a Microsoft Team to the group.
When i use the beta API i will get a code InvalidRequest, "Calling this API using MSGraph Application Permissions is not supported."
The request i am sending is a PUT with "https://graph.microsoft.com/beta/groups/{id}/team" with id the group id. Also i am sure the bearer token is ok, since other requests such as creating an office 365 group work fine.
Setting delegated permissions in Azure app registration or granting permissions didnt seem to work. Is this a beta issue for now or is there something else i should be looking for?
See the below error as example :
{
"error": {
"code": "InvalidRequest",
"message": "Calling this API using MSGraph Application Permissions is
not supported.",
"innerError": {
"request-id": "c4c28d6c-e7f2-4817-bdc7-c5985de61c92",
"date": "2018-06-19T19:18:22"
}
}
}
Regards,
Jos Eilers
App-only permissions are not currently supported. It only works with delegated permissions and that too for work or school accounts. Wont work with Personal MS account
At my end, I am making a PUT request to the /beta/groups/<group id>/team endpoint with the below mentioned payload and it works:
{
"memberSettings": {
"allowCreateUpdateChannels": true
},
"messagingSettings": {
"allowUserEditMessages": true,
"allowUserDeleteMessages": true
},
"funSettings": {
"allowGiphy": true,
"giphyContentRating": "strict"
}
}
reference - Create team - Beta documentation

Resources