Azure B2C - Custom Policy - Error connecting identity provider - azure-active-directory

I've been trying to add a custom policy for Azure AD B2C to connect with Autodesk Forge, following steps on https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-get-started-custom?tabs=applications.
I modified the bit for Facebook's ClaimsProvider with the following:
<ClaimsProvider>
<!-- The following Domain element allows this profile to be used if the request comes with domain_hint
query string parameter, e.g. domain_hint=facebook.com -->
<Domain>autodesk.com</Domain>
<DisplayName>AutodeskForge</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="FORGE-OAUTH">
<!-- The text in the following DisplayName element is shown to the user on the claims provider
selection screen. -->
<DisplayName>Forge</DisplayName>
<Protocol Name="OAuth2" />
<Metadata>
<Item Key="authorization_endpoint">https://developer.api.autodesk.com/authentication/v1/authorize</Item>
<Item Key="AccessTokenEndpoint">https://developer.api.autodesk.com/authentication/v1/gettoken</Item>
<Item Key="ClaimsEndpoint">https://developer.api.autodesk.com/userprofile/v1/users/#me</Item>
<Item Key="ProviderName">AutodeskForge</Item>
<Item Key="HttpBinding">POST</Item>
<Item Key="UsePolicyInRedirectUri">0</Item>
<!-- The Facebook required HTTP GET method, but the access token response is in JSON format from 3/27/2017 -->
<Item Key="AccessTokenResponseFormat">json</Item>
<Item Key="ClaimsEndpointFormat">json</Item>
</Metadata>
<CryptographicKeys>
<Key Id="client_secret" StorageReferenceId="B2C_1A_ForgeSecret" />
</CryptographicKeys>
<InputClaims />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="userId" />
<OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="firstName" />
<OutputClaim ClaimTypeReferenceId="surname" PartnerClaimType="lastName" />
<OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="userName" />
<OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="emailId" />
<OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="autodesk.com" AlwaysUseDefaultValue="true" />
<OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
</OutputClaims>
<OutputClaimsTransformations>
<OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
<OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
<OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
</OutputClaimsTransformations>
<UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
And also replaced the claims provider id on the user journey from Facebook-OAUTH to FORGE_OAUTH.
When run, it does redirect to Autodesk Forge authorize endpoint properly, but then it fails when trying to connect to the identity provider, returning the below error:
AADB2C90289: We encountered an error connecting to the identity provider. Please try again later.
Correlation ID: 188d934d-f1f0-48c5-98c4-917b032b94d2
Timestamp: 2019-11-29 10:54:49Z
Error Example
I'm not very experienced with AAD B2C, but it seems I might just being missing one step at some point.
When adding Application Insight, the trace log outputs this:
[
{
"Kind": "Headers",
"Content": {
"UserJourneyRecorderEndpoint": "urn:journeyrecorder:applicationinsights",
"CorrelationId": "99e13295-a206-449c-b011-a33422112b29",
"EventInstance": "Event:ClaimsExchange",
"TenantId": "alvarob2c.onmicrosoft.com",
"PolicyId": "B2C_1A_signup_signin"
}
},
{
"Kind": "Transition",
"Content": {
"EventName": "ClaimsExchange",
"StateName": "Initial"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.ClaimsExchangeMessageValidationHandler"
},
{
"Kind": "Transition",
"Content": {
"EventName": "ClaimsExchange",
"StateName": "Microsoft.Cpim.Protocols.PartnerProtocolException"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.IsPartnerErrorReachesMaximumRetriesHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"Statebag": {
"MACHSTATE": {
"c": "2019-11-29T11:07:31.6899756Z",
"k": "MACHSTATE",
"v": "Microsoft.Cpim.Protocols.PartnerProtocolException",
"p": true
},
"JC": {
"c": "2019-11-29T11:07:27.797697Z",
"k": "JC",
"v": "en-US",
"p": true
},
"ORCH_CS": {
"c": "2019-11-29T11:07:27.953952Z",
"k": "ORCH_CS",
"v": "2",
"p": true
},
"ORCH_IDX": {
"c": "2019-11-29T11:07:27.953952Z",
"k": "ORCH_IDX",
"v": "0",
"p": true
},
"RA": {
"c": "2019-11-29T11:07:27.953952Z",
"k": "RA",
"v": "0",
"p": true
},
"RPP": {
"c": "2019-11-29T11:07:27.797697Z",
"k": "RPP",
"v": "OAUTH2",
"p": true
},
"RPIPP": {
"c": "2019-11-29T11:07:27.797697Z",
"k": "RPIPP",
"v": "OAuth2ProtocolProvider",
"p": true
},
"OTID": {
"c": "2019-11-29T11:07:27.797697Z",
"k": "OTID",
"v": "alvarob2c.onmicrosoft.com",
"p": true
},
"IC": {
"c": "2019-11-29T11:07:27.9383272Z",
"k": "IC",
"v": "True",
"p": true
},
"MSG(283863a3-02dd-4c87-b4ae-2500a398fed4)": {
"c": "2019-11-29T11:07:27.9383272Z",
"k": "MSG(283863a3-02dd-4c87-b4ae-2500a398fed4)",
"v": "{\"TenantId\":\"alvarob2c.onmicrosoft.com\",\"PolicyId\":\"B2C_1A_signup_signin\",\"RedirectUri\":\"https://jwt.ms/\",\"AdditionalParameters\":{\"p\":\"B2C_1A_signup_signin\"},\"Nonce\":\"defaultNonce\",\"ClientId\":\"4b03fe96-24d9-40b5-b01d-c45b95422b31\",\"ResponseType\":\"id_token\",\"ResponseRedirector\":{\"URI\":\"https://jwt.ms\",\"D\":false,\"WF\":true,\"R\":false},\"Scope\":\"openid\",\"AppModelVersion\":1,\"ScopedProviders\":[]}",
"p": true,
"t": "OAuth2"
},
"IMESSAGE": {
"c": "2019-11-29T11:07:27.9383272Z",
"k": "IMESSAGE",
"v": "283863a3-02dd-4c87-b4ae-2500a398fed4",
"p": true
},
"TAGE": {
"c": "2019-11-29T11:07:31.5024363Z",
"k": "TAGE",
"v": "ForgeExchange",
"p": true
},
"SE": {
"c": "2019-11-29T11:07:27.953952Z",
"k": "SE",
"v": "Social",
"p": true
},
"CMESSAGE": {
"c": "2019-11-29T11:07:31.3461838Z",
"k": "CMESSAGE",
"v": "283863a3-02dd-4c87-b4ae-2500a398fed4",
"p": true
},
"ComplexItems": "_MachineEventQ, REPRM, TCTX, M_EXCP"
},
"PredicateResult": "False"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.IsPartnerReauthenticateActionHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"PredicateResult": "False"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.IsPartnerClientInvalidActionHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"PredicateResult": "False"
}
},
{
"Kind": "Predicate",
"Content": "Web.TPEngine.StateMachineHandlers.NoOpHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"PredicateResult": "True"
}
},
{
"Kind": "Action",
"Content": "Web.TPEngine.SSO.SSOSessionEndHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true
}
},
{
"Kind": "Action",
"Content": "Web.TPEngine.StateMachineHandlers.SendErrorHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true,
"RecorderRecord": {
"Values": [
{
"Key": "SendErrorTechnicalProfile",
"Value": "OAuth2ProtocolProvider"
},
{
"Key": "Exception",
"Value": {
"Kind": "Handled",
"HResult": "80131500",
"Message": "We encountered an error connecting to the identity provider. Please try again later.",
"Data": {
"IsPolicySpecificError": false
}
}
}
]
},
"Statebag": {
"SE": {
"c": "2019-11-29T11:07:31.6899756Z",
"k": "SE",
"v": "",
"p": true
}
}
}
},
{
"Kind": "Action",
"Content": "Web.TPEngine.StateMachineHandlers.TransactionEndHandler"
},
{
"Kind": "HandlerResult",
"Content": {
"Result": true
}
}
]

I was also receiving this error because the client ID I was passing to the identity provider was not authorized for the redirect URI I was sending to it. I had duplicated a custom policy and left the client ID for the original policy which, in the IDP, was authorized to redirect only to the original policy.

I had the same error/symptoms with a different IDP but my root cause was different. In my case, my B2C policy was sending token requests using GET instead of POST and the IDP server only supported POST. To correct that, I had to set the following in the metadata section of my OAuth2 technical profile.
<Item Key="HttpBinding">POST</Item>

Related

'Send an Email' parameter 'attachment content' cannot be null

I'm creating an Azure Logic App to email a CSV file with data. When there is no data, the Send_an_email_(V2) step is failing and I see the following error in its output:
Parameter 'Attachment Content' cannot be null or empty.
The Send_an_email_(V2) action in the Azure Logic App gets part of it's input from the output of a preceding Create_CSV_table action. It uses the body of the Create_CSV_table output as shown below, in order to construct ContentBytes for an email attachment:
"actions": {
"Create_CSV_table": {
"inputs": {
"format": "CSV",
"from": "#body('Parse_JSON')"
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Table"
},
"Send_an_email_(V2)": {
"inputs": {
"body": {
"Attachments": [
{
"ContentBytes": "#{base64(body('Create_CSV_table'))}",
"Name": "report.csv"
}
],
"Body": "<p></p>",
"Subject": "My Report",
"To": "me#email.com"
},
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "post",
"path": "/v2/Mail"
},
"runAfter": {
"Create_CSV_table": [
"Succeeded"
]
},
"type": "ApiConnection"
}
When there is no data input into the Create_CSV_table step, the Create_CSV_table step is successful, and the raw output for the Create_CSV_table step shows an empty body as follows:
{
"body": ""
}
Raw input for the failing Send_an_email_(V2) step
{
HTTP stuff ...,
"body": {
"Attachments": [
{
"ContentBytes": "",
"Name": "report.csv"
}
],
"Body": "<p></p>",
"Subject": "Report",
"To": "me#mail.com"
}
}
Raw output for the failing Send_an_email_(V2) step
{
HTTP stuff ...,
"body": {
"status": 400,
"message": "Parameter 'Attachment Content' cannot be null or empty.\r\nclientRequestId: 887e3968-c7e9-4c35-b588-f76fd0e51545",
"error": {
"message": "Parameter 'Attachment Content' cannot be null or empty."
},
"source": "office365-ase.azconn-ase.p.azurewebsites.net"
}
}
How do I handle this? Do I need to implement my own null handling for the "ContentBytes" of the Send_an_email_(V2) input? If so, how do I do that? Or is there another way to handle this. I want an empty email to be sent when there is no CSV content.
I figured out that #{base64(body('Create_CSV_table'))} is an Azure Logic Apps expression (denoted by #), containing functions that act on the JSON for the body of the output of Create_CSV_table and that the enclosing {} results in the output of the expression being a string.
After the Last step you can send to storage account using Create blob(V2) Connection with .csv file extension and then send the same blob content using Get blob content(V2) Connection then Send an email.
Here are the screenshots of LogicApp
In outlook:
Here is the workflow
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Create_CSV_table_2": {
"inputs": {
"format": "CSV",
"from": "#variables('Array')"
},
"runAfter": {
"For_each_2": [
"Succeeded"
]
},
"type": "Table"
},
"Create_blob_(V2)": {
"inputs": {
"body": "#body('Create_CSV_table_2')",
"headers": {
"ReadFileMetadataFromServer": true
},
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "post",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/files",
"queries": {
"folderPath": "/ch1container2408",
"name": "TestSample1.csv",
"queryParametersSingleEncoded": true
}
},
"runAfter": {
"Create_CSV_table_2": [
"Succeeded"
]
},
"runtimeConfiguration": {
"contentTransfer": {
"transferMode": "Chunked"
}
},
"type": "ApiConnection"
},
"For_each_2": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "Array",
"value": {
"created_at": "#items('For_each_2')['created_at']",
"funds": "#items('For_each_2')['funds']",
"id": "#items('For_each_2')['id']",
"pair": "#items('For_each_2')['market']",
"price": "#items('For_each_2')['price']",
"side": "#items('For_each_2')['side']",
"volume": "#items('For_each_2')['volume']"
}
},
"runAfter": {},
"type": "AppendToArrayVariable"
}
},
"foreach": "#body('Parse_JSON')",
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "Foreach"
},
"Get_blob_content_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/files/#{encodeURIComponent(encodeURIComponent('/<Your Container>','/<Your File>.csv'))}/content",
"queries": {
"inferContentType": true
}
},
"runAfter": {
"Create_blob_(V2)": [
"Succeeded"
]
},
"type": "ApiConnection"
},
"HTTP": {
"inputs": {
"method": "GET",
"uri": "https://api.wazirx.com/api/v2/trades?market=btcusdt"
},
"runAfter": {},
"type": "Http"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "Array",
"type": "array"
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_2": {
"inputs": {
"variables": [
{
"name": "Table",
"type": "array"
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#body('HTTP')",
"schema": {
"items": {
"properties": {
"created_at": {
"type": "string"
},
"funds": {
"type": "string"
},
"id": {
"type": "integer"
},
"market": {
"type": "string"
},
"price": {
"type": "string"
},
"side": {},
"volume": {
"type": "string"
}
},
"required": [
"id",
"market",
"price",
"volume",
"funds",
"created_at",
"side"
],
"type": "object"
},
"type": "array"
}
},
"runAfter": {
"HTTP": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Send_an_email_(V2)": {
"inputs": {
"body": {
"Attachments": [
{
"ContentBytes": "#{base64(body('Get_blob_content_(V2)'))}",
"Name": "#body('Create_blob_(V2)')?['Name']"
}
],
"Body": "<p>TABLE TEST</p>",
"Subject": "Test",
"To": "<To Address>"
},
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "post",
"path": "/v2/Mail"
},
"runAfter": {
"Get_blob_content_(V2)": [
"Succeeded"
]
},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"azureblob": {
"connectionId": "<Your ConnectionId>",
"connectionName": "azureblob",
"id": "<Id>"
},
"office365": {
"connectionId": "<Your ConnectionId>",
"connectionName": "office365",
"id": "<Your Id>"
}
}
}
}
}

Invalid response from webhook: Failed to translate JSON to ExecuteHttpResponse

I have a webhook from my google assistant new actions builder platform. Webhook code is written in the dotnet vs2019. I have followed the webhook request and response format and sample jsons provided in the below links.
https://developers.google.com/assistant/conversational/reference/rest/v1/TopLevel/fulfill#User
https://developers.google.com/assistant/conversational/webhooks#request-json_1
But when I test assistant action, it is failing. Below is request and response json from logs in the google assistant test simulator.Error message just says"Invalid response from webhook: Failed to translate JSON to ExecuteHttpResponse." I don't know why it is not valid. Can someone help me resolving this.
{
"requestJson": {
"handler": {
"name": "agentcube"
},
"intent": {
"name": "",
"params": {
"phone": {
"original": "1234562869",
"resolved": 1234562869
}
},
"query": "1234562869"
},
"scene": {
"name": "Start",
"slotFillingStatus": "FINAL",
"slots": {
"Zip": {
"mode": "REQUIRED",
"status": "SLOT_UNSPECIFIED",
"updated": false,
"value": 37122
},
"Phone": {
"mode": "REQUIRED",
"status": "SLOT_UNSPECIFIED",
"updated": true,
"value": 1234562869
},
"FName": {
"mode": "REQUIRED",
"status": "SLOT_UNSPECIFIED",
"updated": false,
"value": "john doe"
}
},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
},
"session": {
"id": "ABwppHFkFuGBF-UawPmIkxWpkfM1Hb5An7h8KnjR302zukmBoKA1NqDp7DfePGzYsyxT5oy--wg5Jkjj",
"params": {
"Phone": 1234562869,
"FName": "john doe",
"Zip": 37122
},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {},
"accountLinkingStatus": "NOT_LINKED",
"verificationStatus": "VERIFIED",
"packageEntitlements": [],
"gaiamint": "",
"permissions": [],
"lastSeenTime": "2021-01-28T19:21:28Z"
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
}
Invalid response from webhook: Failed to translate JSON to ExecuteHttpResponse..
{
"responseJson": {
"Session": {
"Id": "ABwppHFkFuGBF-UawPmIkxWpkfM1Hb5An7h8KnjR302zukmBoKA1NqDp7DfePGzYsyxT5oy--wg5Jkjj",
"Params": {
"Phone": 1234562869,
"Zip": 37122,
"FName": "john doe"
}
},
"Prompt": {
"Override": false,
"FirstSimple": {
"Speech": "My webhook response",
"Text": "My response from webhook"
}
},
"Scene": {
"Name": "Start",
"SlotFillingStatus": "FINAL",
"Slots": {
"Phone": {
"Mode": "REQUIRED",
"Status": "SLOT_UNSPECIFIED",
"Updated": true,
"value": 1234562869
},
"FName": {
"Mode": "REQUIRED",
"Status": "SLOT_UNSPECIFIED",
"Updated": false,
"value": "john doe"
},
"Zip": {
"Mode": "REQUIRED",
"Status": "SLOT_UNSPECIFIED",
"Updated": false,
"value": 37122
}
},
"Next": {
"Name": "actions.scene.END_CONVERSATION"
}
}
}
}
Make sure the response that you code is returning is json by checking with a linter, which this seems to checks (i.e. everything inside the ResponseJson {}
Please see my response to a similar issue at https://stackoverflow.com/a/66512370/10537202 to use the webhook playground.

multipart/form-data post api works from postman but do not working from react native as expected

I am integrating an API in react native, where I am facing a parsing error. But, from the postman, it works fine.
I have tried to send an image through uri, blob, base64 string but facing the same issue.
Below is my react-native code:
var data = new FormData();
data.append("ImgInput", "/IMG_20161229_140335993.jpg");
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "http://212.48.69.65:7465/Core.svc/UploadImage?ApplicationName=www_spoiltpigrewards_com&SessionToken=7E2BE649-3136-4074-9B88-670D717C5828&UserName=jatin1#gmail.com&StoreName=Cooperative&NumberOfProducts=2&Multishot=true&MultishotGuid=00000000-0000-0000-0000-000000000000&FileNumber=1&MaxFileNumber=2");
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.send(data);
below is postman collection in json format. it works fine. I want same output from react-native code.
{
"info": {
"_postman_id": "7a0149d0-c96c-4431-8978-1b619968edf7",
"name": "SpoiltPig",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "http://212.48.69.65:7465/Core.svc/UploadImage?ApplicationName=www_spoiltpigrewards_com&SessionToken=7E2BE649-3136-4074-9B88-670D717C5828&UserName=jatin1#gmail.com&StoreName=Cooperative&NumberOfProducts=2&Multishot=true&MultishotGuid=00000000-0000-0000-0000-000000000000&FileNumber=1&MaxFileNumber=2",
"request": {
"method": "POST",
"header": [
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "ImgInput",
"value": null,
"type": "file"
}
]
},
"url": {
"raw": "http://212.48.69.65:7465/Core.svc/UploadImage?ApplicationName=www_spoiltpigrewards_com&SessionToken=7E2BE649-3136-4074-9B88-670D717C5828&UserName=jatin1#gmail.com&StoreName=Cooperative&NumberOfProducts=2&Multishot=true&MultishotGuid=00000000-0000-0000-0000-000000000000&FileNumber=1&MaxFileNumber=2",
"protocol": "http",
"host": [
"212",
"48",
"69",
"65"
],
"port": "7465",
"path": [
"Core.svc",
"UploadImage"
],
"query": [
{
"key": "ApplicationName",
"value": "www_spoiltpigrewards_com"
},
{
"key": "SessionToken",
"value": "7E2BE649-3136-4074-9B88-670D717C5828"
},
{
"key": "UserName",
"value": "jatin1#gmail.com"
},
{
"key": "StoreName",
"value": "Cooperative"
},
{
"key": "NumberOfProducts",
"value": "2"
},
{
"key": "Multishot",
"value": "true"
},
{
"key": "MultishotGuid",
"value": "00000000-0000-0000-0000-000000000000"
},
{
"key": "FileNumber",
"value": "1"
},
{
"key": "MaxFileNumber",
"value": "2"
}
]
}
},
"response": []
}
]
}

Allow SOLR core only for a single user

I can't find any information on how to allow access to specific SOLR core just for a single user. I am using SOLR7. This is what I've got:
security.json
{
"authentication": {
"blockUnknown": true,
"class": "solr.BasicAuthPlugin",
"credentials": {
"test_admin": "xxx",
"infographics": "xxx",
"test_user": "xxx"
},
"": {
"v": 0
}
},
"authorization": {
"class": "solr.RuleBasedAuthorizationPlugin",
"permissions": [
{
"name": "all",
"role": "admin",
"index": 1
},
{
"name": "update",
"role": "general",
"index": 2
},
{
"name": "read",
"role": [
"general",
"infographics",
"test_user"
],
"index": 3
},
{
"name": "collection-admin-read",
"role": "general",
"index": 4
},
{
"name": "core-admin-read",
"role": "general",
"index": 5
},
{
"name": "core-specific-permission",
"collection": "test-core",
"role": "test_user",
"before": 3,
"index": 6
}
],
"user-role": {
"test_admin": [
"admin",
"general"
],
"infographics": "infographics",
"test_user": "test_user"
},
"": {
"v": 0
}
}
}
I've added a permission for collection "test-core":
{
"name": "core-specific-permission",
"collection": "test-core",
"role": "test_user",
"before": 3,
"index": 6
}
I authenticate with test_user when calling: /solr/test-core/select?q=*:*, this works fine, but it also can access other cores, for e.g.: /solr/other-core/select?q=*:*.
If I remove test_user from read permission:
{
"name": "read",
"role": [
"general",
"infographics"
],
"index": 3
},
then I am not able to query any core. Getting 403. For test_user I'd like to allow access to only this core /solr/test-core/select?q=*:* and nothing else. Any idea how can I achieve this?

Send workflow information to custom connector

I need help with sending workflow information in header/body of calls to custom connector. I am trying to load a drop down list in one of the parameters of a logic app using values returned from an API call. The API end point requires basic workflow information such as the resource group and workflow name which are normally available in headers of http requests from logic app execution.
Normally when I use #{workflow().name} in logic app's json, it is substituted with the workflow name. In case of custom connector, the WDL syntax is passed as is without any transformation.
Here is a simplified swagger json with all relevant sections.
{
"swagger": "2.0",
"info": {
"title": "{{dynamicHostName}}",
"version": "1.0.0"
},
"host": "{{dynamicHostName}}",
"basePath": "/",
"schemes": [
"https"
],
"paths": {
"/sftpsource": {
"post": {
"operationId": "SftpSource",
"summary": "Sftp as source system",
"description": "Use Sftp as source system",
"produces": [
"application/json"
],
"consumes": [
"application/json"
],
"parameters": [
{
"name": "params",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"hostName": {
"type": "string",
"x-ms-summary": "Host Name",
"x-ms-visibility": "advanced"
},
"portNumber": {
"type": "string",
"x-ms-summary": "Port Number",
"x-ms-visibility": "advanced"
},
"userName": {
"type": "string",
"x-ms-summary": "User Name",
"x-ms-visibility": "advanced"
},
"password": {
"type": "string",
"x-ms-summary": "Password",
"x-ms-visibility": "advanced"
},
"filePath": {
"type": "string",
"x-ms-summary": "File Path"
},
"system": {
"type": "string",
"x-ms-visibility": "advanced",
"x-ms-summary": "System",
"x-ms-dynamic-values": {
"operationId": "GetTaggedSystems",
"parameters": {
"workflow-name": "#{workflow().name}"
},
"value-path": "systemId",
"value-title": "systemName"
}
}
}
}
}
],
"responses": {
"202": {
"description": "Request is queued"
},
"500": {
"description": "Server Error"
}
}
}
},
"/taggedSystems" : {
"get": {
"operationId": "GetTaggedSystems",
"summary": "Tagged Systems",
"x-ms-visibility": "advanced",
"description": "Get all systems tagged to this flow",
"parameters": [
{
"name": "workflow-name",
"in": "header",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/TaggedSystems"
}
},
"202": {
"description": "Work is still in progress"
},
"500": {
"description": "An error occured while trying to fetch tagged systems."
}
}
}
}
},
"definitions": {
"TaggedSystems": {
"type": "array",
"items": {
"type": "object",
"properties": {
"systemId": {
"type": "string"
},
"systemName": {
"type": "string"
}
},
"required": [
"systemId",
"systemName"
]
}
}
}
}
You can have an internal parameter defined as header/body where you can pass dynamic expressions of what you need from the workflow environment at the time of execution of the flow.
For complete information regarding the flow, you can pass #{workflow()} as an internal parameter.
Hope it helps.

Resources