Azure AD B2C REST API : Create Bulk Local Accounts - azure

Is it possible to create users in bulk via the REST API. Same as we do for single user in the below URL.
https://graph.windows.net/{MYADB2C}.onmicrosoft.com/users?api-version=1.6
We have the provision via the Azure portal but could'nt find anything with REST API.
UPDATED
Sample request for Batch processing
POST https://graph.windows.net/{}.onmicrosoft.com/$batch?api-version=1.6
Headers :
Authorization : {token}
Content-Type : multipart/mixed; boundary=changeset_***********
Body :
{
"requests": [
{
"id": "1",
"method": "POST",
"url": "/users",
"body": {
"accountEnabled": true,
"creationType": "LocalAccount",
"displayName": "test1#gamil.com",
"passwordPolicies": "DisablePasswordExpiration, DisableStrongPassword",
"passwordProfile": {
"password": "***",
"forceChangePasswordNextLogin": false
},
"signInNames": [
{
"type": "emailAddress",
"value": "test1#gamil.com"
}
]
},
"headers": {
"Content-Type": "application/json"
}
},
{
"id": "2",
"method": "POST",
"url": "/users",
"body": {
"accountEnabled": true,
"creationType": "LocalAccount",
"displayName": "test2#gmail.com",
"passwordPolicies": "DisablePasswordExpiration, DisableStrongPassword",
"passwordProfile": {
"password": "***",
"forceChangePasswordNextLogin": false
},
"signInNames": [
{
"type": "emailAddress",
"value": "test1#gamil.com"
}
]
},
"headers": {
"Content-Type": "application/json"
}
}
]
}

Yes. You can batch operations by referring to Batch processing | Graph API concepts.
But we recommend you use Microsoft Graph API JSON Batching instead of Azure AD Graph Batch processing because Azure AD Graph content is no longer updated.
An example using Microsoft Graph API here:
POST https://graph.microsoft.com/v1.0/$batch
Accept: application/json
Content-Type: application/json
{
"requests": [
{
"id": "1",
"method": "POST",
"url": "/users",
"body": {
"accountEnabled": true,
"displayName": "at1",
"mailNickname": "at1",
"userPrincipalName": "at1#**.onmicrosoft.com",
"passwordProfile" : {
"forceChangePasswordNextSignIn": true,
"password": "password-value"
}
},
"headers": {
"Content-Type": "application/json"
}
},
{
"id": "2",
"method": "POST",
"url": "/users",
"body": {
"accountEnabled": true,
"displayName": "at2",
"mailNickname": "at2",
"userPrincipalName": "at2#**.onmicrosoft.com",
"passwordProfile" : {
"forceChangePasswordNextSignIn": true,
"password": "password-value"
}
},
"headers": {
"Content-Type": "application/json"
}
},
{
"id": "3",
"method": "POST",
"url": "/users",
"body": {
"accountEnabled": true,
"displayName": "at3",
"mailNickname": "at3",
"userPrincipalName": "at3#**.onmicrosoft.com",
"passwordProfile" : {
"forceChangePasswordNextSignIn": true,
"password": "password-value"
}
},
"headers": {
"Content-Type": "application/json"
}
}
]
}
You can have a quick test in Microsoft Graph Explorer.

Related

Azure Logic App not able create client certificate authentication with converted base64 encoded pfx

I want to get the token information for ADP Client through Azure Logic App. I have the Client Certificate from ADP so I decided to use HTTP trigger from Logic App and selected authentication type "Client Certificate".
Since I cant directly use certificate in Logic app so I converted certificate into base64Encoded .pfx format, and certificate is not having any password.
below is the sample code for the request
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {},
"contentVersion": "1.0.0.0",
"outputs": {},
"triggers": {
"HTTP": {
"inputs": {
"authentication": {
"pfx": "convertedbase64string",
"type": "ClientCertificate"
},
"body": "grant_type=client_credentials&client_id=ClientId&client_secret=client_secret",
"headers": {
"content-type": "application/x-www-form-urlencoded"
},
"method": "POST",
"uri": "https://accounts.adp.com/auth/oauth/v2/token"
},
"recurrence": {
"frequency": "Month",
"interval": 15
},
"type": "Http"
}
}
},
"kind": "Stateful"
}
above request returns me bad request, can anyone help me what is going wrong here?
For converting into base64 I used below steps in power shell
$pfx_cert = get-content 'C:\sample\adpcertificate.pfx' -Encoding Byte
$output =[Convert]::ToBase64String($pfx_cert)
$output
I tried same request with client certificate using postman which is working fine, but not able to get succeed with Logic App.
Any help is much appreciated.
There are only few differences between the headers sent from Postman and the Logic App. The main difference is that Postman also sends the accept-header: "Accept": "*/*" and leaves out alle the x-ms-* headers from the logic app.
I created a Logic App with http-trigger, which I post to from Postman and Logic App to inspect the changes:
With Postman
{
"headers": {
"Connection": "keep-alive",
"Accept": "*/*",
"Accept-Encoding": "br,gzip,deflate",
"Host": "....westeurope.logic.azure.com:443",
"User-Agent": "PostmanRuntime/7.28.4",
"Postman-Token": "...-baea-4e89-9bf6-490a63968b5d",
"Content-Length": "76",
"Content-Type": "application/x-www-form-urlencoded"
},
"body": {
"$content-type": "application/x-www-form-urlencoded",
"$content": "Z3JhbnRfdHlwZT1jbGllbnRfY3JlZGVudGlhbHMmY2xpZW50X2lkPUNsaWVudElkJmNsaWVudF9zZWNyZXQ9Y2xpZW50X3NlY3JldA==",
"$formdata": [
{
"key": "grant_type",
"value": "client_credentials"
},
{
"key": "client_id",
"value": "ClientId"
},
{
"key": "client_secret",
"value": "client_secret"
}
]
}
}
With Logic App
{
"headers": {
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip,deflate",
"Accept-Language": "en",
"Host": "...westeurope.logic.azure.com",
"User-Agent": "azure-logic-apps/1.0,(workflow ...; version ...)",
"x-ms-trigger-callback-url": "https://....westeurope.logic.azure.com/ <...>",
"x-ms-trigger-type": "Http",
"x-ms-workflow-id": "...",
"x-ms-workflow-version": "...",
"x-ms-workflow-name": "myworkflowname",
"x-ms-workflow-system-id": "/locations/westeurope/scaleunits/...",
"x-ms-workflow-run-id": "...",
"x-ms-workflow-operation-name": "HTTP",
"x-ms-execution-location": "westeurope",
"x-ms-workflow-subscription-id": "...",
"x-ms-workflow-resourcegroup-name": "..",
"x-ms-tracking-id": "...",
"x-ms-correlation-id": "...",
"x-ms-client-request-id": "...",
"x-ms-activity-vector": "...",
"Content-Length": "76",
"Content-Type": "application/x-www-form-urlencoded"
},
"body": {
"$content-type": "application/x-www-form-urlencoded",
"$content": "Z3JhbnRfdHlwZT1jbGllbnRfY3JlZGVudGlhbHMmY2xpZW50X2lkPUNsaWVudElkJmNsaWVudF9zZWNyZXQ9Y2xpZW50X3NlY3JldA==",
"$formdata": [
{
"key": "grant_type",
"value": "client_credentials"
},
{
"key": "client_id",
"value": "ClientId"
},
{
"key": "client_secret",
"value": "client_secret"
}
]
}
}
Solution
My solution would be to manually add the Accept-Header in the post request in the Logic App.
"headers": {
"Accept": "*/*",
// ...
},
I sadly don't have an ADP account to verify this, but I've seen other APIs break when no accept header is sent.

How to form URLs with loopback rest connector?

I created an API endpoint like:
GET /etablissementDetails/{id}
Here is my datasources.json file:
"etablissementDetailsREST": {
"name": "etablissementDetailsREST",
"crud": false,
"connector": "rest",
"debug": false,
"options": {
"headers": {
"accept": "application/json",
"content-type": "application/json"
},
"strictSSL": false
},
"operations": [
{
"template": {
"method": "GET",
"url": "https://data.education.gouv.fr/api/records/1.0/search/?dataset=fr-en-adresse-et-geolocalisation-etablissements-premier-et-second-degre",
"headers": {
"accepts": "application/json",
"content-type": "application/json"
},
"query": {
"q": "{id}"
},
"options": {
"strictSSL": true,
"useQuerystring": true
},
"responsePath": "$.records.*"
},
"functions": {
"{id}": ["id"]
}
}
]}
In loopback explorer, if I enter as an idea and click on Try me out (Run the GET), I am getting the following:
http://localhost:3000/api/v1/etablissementDetails/{id}?id=0593904Y
I would like the {id} to be replaced by 0593904Y directly in the URL to become http://localhost:3000/api/v1/etablissementDetails/0593904Y

submitting a form through node as if connected to a site

I'm trying to create an automated tool that will submit a form so that it can detect changes in the response over time.
Normally, to submit this form I log in to a site and submit the form.
When trying to send the exact same request through Postman or a small node app I made, I get status 302 (while resending the request through firefox debugger works fine).
I even tried to use the HAR exported from the browser.
this is the code I use:
request({
har:{
"bodySize": 320,
"method": "POST",
"url": "https://***.com/url-to-send-the-form",
"httpVersion": "HTTP/2.0",
"headers": [
{
"name": "Host",
"value": "www.***.com"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0"
},
{
"name": "Accept",
"value": "*/*"
},
{
"name": "Accept-Language",
"value": "en-US,en;q=0.5"
},
{
"name": "Accept-Encoding",
"value": "gzip, deflate, br"
},
{
"name": "Referer",
"value": "https://***.com/page-where-the-form-is/"
},
{
"name": "Content-Type",
"value": "application/x-www-form-urlencoded; charset=UTF-8"
},
{
"name": "X-Requested-With",
"value": "XMLHttpRequest"
},
{
"name": "Content-Length",
"value": "320"
},
{
"name": "Cookie",
"value": "visid_incap_1156372=***; _pk_id.7.32fa=***; _pk_ref.7.32fa=***; ASP.NET_SessionId=***; __RequestVerificationToken=***; BIGipServerMFT-Frontends=***; incap_ses_1051_1156372=***; _pk_ses.7.32fa=***; windID_1b5aa482-1126-4c17-a65f-dbac1e05cfb9=***; .AspNet.ApplicationCookie=***; family_Composition=***"
},
{
"name": "Connection",
"value": "keep-alive"
}
],
"cookies": [
{
"name": "visid_incap_1156372",
"value": "***"
},
{
"name": "_pk_id.7.32fa",
"value": "***"
},
{
"name": "_pk_ref.7.32fa",
"value": "***"
},
{
"name": "ASP.NET_SessionId",
"value": "***"
},
{
"name": "__RequestVerificationToken",
"value": "***"
},
{
"name": "BIGipServerMFT-Frontends",
"value": "***"
},
{
"name": "incap_ses_1051_1156372",
"value": "***"
},
{
"name": "_pk_ses.7.32fa",
"value": "***"
},
{
"name": "windID_1b5aa482-1126-4c17-a65f-dbac1e05cfb9",
"value": "***"
},
{
"name": ".AspNet.ApplicationCookie",
"value": "***"
},
{
"name": "family_Composition",
"value": "***"
}
],
"queryString": [],
"headersSize": 1717,
"postData": {
"mimeType": "application/x-www-form-urlencoded",
"params": [
{
"name": "key",
"value": "{val}"
}
],
"text": "key=val-url-encoded"
}
}
}, function (error, response, body) {
console.log(response.statusCode);//returns 302
});
Help will be very much appreciated

Google Street View Publish return's "Photo does not have upload reference." after statusCode 200

I'm using NodeJS to upload panoramic images.
When I make #2 informed in the Google documentation, I get the following return:
Request
{
"url": "UPLOAD_URL",
"body": "/PATH_TO_PANO/pano.jpg",
"method": "POST",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "image/jpeg"
}
}
Response
{
"statusCode": 200,
"body": "",
"headers": {
"x-guploader-uploadid": "AEnB2UoJt4gvmmU6gXZvWDRu4b0DUCeT5vuPKLGcZqM4Tzo9HssCLoloTgAACRmxmP0U5DDYvHXpThCjRslW80bEKLZjUjJB3QNZ5w- j0jd8jdtVnH8X0c",
"content-length": "0",
"date": "Tue, 26 Sep 2017 21:05:17 GMT",
"server": "UploadServer",
"content-type": "text/html; charset=UTF-8",
"alt-svc": "quic=\":443\"; ma=2592000; v=\"39,38,37,35\"",
"connection": "close"
},
"request": {
"uri": {
"protocol": "https:",
"slashes": true,
"auth": null,
"host": "streetviewpublish.googleapis.com",
"port": 443,
"hostname": "streetviewpublish.googleapis.com",
"hash": null,
"search": null,
"query": null,
"pathname": "/media/user/USER_ID/photo/PHOTO_ID",
"path": "/media/user/USER_ID/photo/PHOTO_ID",
"href": "https://streetviewpublish.googleapis.com/media/user/USER_ID/photo/PHOTO_ID"
},
"method": "POST",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "image/jpeg",
"content-length": 45
}
}
}
But when I upload the metadata of the photo, I get the following message:
Request
{
"url": "https://streetviewpublish.googleapis.com/v1/photo?key=YOUR_API_KEY",
"method": "POST",
"headers": {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json",
"Content-Length": 9385487
},
"data": {
"uploadReference": {
"uploadUrl": "UPLOAD_URL"
},
"pose": {
"heading": 110,
"latLngPair": {
"latitude": -29.937386,
"longitude": -60.996952
}
},
"captureTime": {
"seconds": 1506448064836
}
}
}
Response
{
"error": {
"code": 400,
"message": "Photo does not have upload reference.",
"status": "INVALID_ARGUMENT"
}
}
There are not many references to basing myself and finding the problem. For that reason I would like the help of someone who may have gone through something similar.
I have replicated your issue. I've encountered this error when I didn't specify the UPLOAD_URL in the request.
{
"error": {
"code": 400,
"message": "Photo upload url does not match required format.",
"status": "INVALID_ARGUMENT",
"details": [
{
...
}
]
}
}
Make sure that you have added the UPLOAD_URL in the request. Check this documentation for more information.

Loopback REST connector POST

I tried to create a model, and connect to my API test server.
Here's the REST datasource configuration :
"postsREST": {
"name": "postsREST",
"connector": "rest",
"operations": [{
"template": {
"method": "GET",
"url": "http://localhost:3001/posts"
},
"functions": {
"find": []
}
}, {
"template": {
"method": "POST",
"url": "http://localhost:3001/posts",
"headers": {
"accept": "application/json",
"content-type": "application/json"
},
"query": {
"title": "{^title}",
"author": "{^author}"
},
"body": {
"title": "{^title}",
"author": "{^author}"
}
},
"functions": {
"create": [
"title",
"author"
]
}
}]
}
The problem is, that when I use the explorer, the generated request url is this:
http://localhost:3000/api/posts/create?title=f&author=f
Instead of:
http://localhost:3000/api/posts
What am I doing wrong? Maybe there is new documentation?
Thanks.
You should use form instead of req or body, if you want the params not to be part of the request-url. req or body will append your parameters to the request URL.
Using form will send your parameters just like a form is submitted using POST method and hence as part of the request body.
So, try the following way for the template section in your code:
"template": {
"method": "POST",
"url": "http://localhost:3001/posts",
"headers": {
"accept": "application/json",
"content-type": "application/json"
},
"form": {
"title": "{^title}",
"author": "{^author}"
}
},
Additionally, I do not see any point in adding the same parameters to the req and body attributes both.

Resources