Azure B2C Custom Policy Precondition not working - azure-ad-b2c

I have a simple Precondition during ValidationTechnicalProfile, that compares claim with a string, I want to Skip that validation step if value matches but it doesn't executes even though the Value is correct:
<Precondition Type="ClaimEquals" ExecuteActionsIf="true">
<Value>myClaim</Value>
<Value>SomeStringValue</Value>
<Action>SkipThisValidationTechnicalProfile</Action>
</Precondition>
When I see b2c-logs I do see myClaim value set to SomeStringValue but it doesn't executes the Action. What am I doing wrong here?
Thanks

I've seen this problem. You haven't shown all the code but have a look at this. That may be the problem i.e.
"myClaim has to be an output claim in the self-asserted TP that calls this validation TP!"

Related

How to delete claims from b2c custom policy claims claims bag (claims collection)?

I am trying to remove all the claims from the claims bag, if a certain step/condition in my custom policy is reached, however I couldn't find any information about that. Then I tried to use the NullClaim Transformation for strings, but I couldn't find anything for numbers, booleans and dates. The working example for string is as follows
<ClaimsTransformation Id="SetDisplayNameToNull" TransformationMethod="NullClaim">
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" TransformationClaimType="claim_to_null" />
</OutputClaims>
</ClaimsTransformation>
Should I just set dates to a really old date like 1970-01-01T00:00:00Z?
Should I just set booleans to true/false depending on their suitable default values?
If yes, how would I go about it, as I can see that I can get currentDateTime, but I am unable to find any documentation setting a specific date value to a date type claim, same goes for the boolean.
You can use this to delete claims in a custom policy.

Scraping the user portal for the CDC Wonder API

Sorry in advance for the novel, I've tried to distill this down into something short and sweet, but find it impossible. I'm really hoping someone can shed some light on this problem.
The project: to build a set of utilities to make using the CDC Wonder API easier.
The Wonder API has several endpoints, in the format of /D140 or /D76, for example.
The endpoint must be hit with a POST request, with a set of query parameters sent as an xml string as a POST data parameter.
The query parameter xml string is complicated. The basic format is
<parameter>
<name></name>
<value></value>
</parameter>
</request-parameters>
The names and values are best understood by going to the user-facing query portal. Each one of the inputs (forms, checkboxes, radio buttons, etc) corresponds to a query parameter. Each parameter name is in the form of a code, such as D76.V9 or O_V27fmode. The value may also be a code, or occasionally could be plaintext, such as *All*.
Each endpoint requires a slightly different set of parameters, and the coding for the values is also different. The CDC does not provide documentation on which parameters each endpoint expects. Their documentation specifically tells you that the best way to find this information is by examining the source code of the user-facing query portal, where each element has its name and value embedded as an attribute.
I've found that you can also retrieve these parameters by opening up the dev tools network tab, submitting a filled out query form, and, after the new page loads with your results, checking the POST call's header form data.
One of the utilities I'm trying to build is to scrape the query portal page and programmatically extract the names and values of all parameters from the HTML source code. Seems simple enough and I think I know how to do it.
But, here's the rub: the URL of the user-facing query portal is the same as the URL for the endpoint that you call. In a web browser, going to this URL (https://wonder.cdc.gov/controller/datarequest/D76) sends you to the query form that you fill out. But when you use that same URL in a request in Python, it expects an xml string of query parameters, otherwise you will get an error.
Is it possible to use the requests library to hit this user portal? I tried setting the referrer to https://wonder.cdc.gov/ucd-icd10.html, which is a page you're redirected to before you can get to the query portal, and you must agree to the terms and conditions. I also tried pulling the form data out of the network tab and sent it as an xml string with my POST request, and got a 500 back -- it's expecting the query parameters (including a specific parameter agreeing to the terms of use, as outlined in the documentation). Here's an example of the code I'm using:
xml_string = '''<query-parameters>
<parameter><name>stage</name> <value>about</value> </parameter> <parameter> <name>saved_id</name> <value></value> </parameter> <parameter> <name>action-I Agree</name> <value>I Agree</value> </parameter> </query-parameters> '''
data = {'request_xml': xml_string}
response = requests.post('https://wonder.cdc.gov/controller/datarequest/D76')
print(response.text)
print(response)
Really curious to know how to crack this nut, what am I missing here? How should I be approaching this problem?
Long time after you asked the question but I think the issue is with the post request is made and also the contents of your data variable.
Also just a note that it should be 'result-parameters' instead of 'query-parameters' in your xml_string.
It does seem that the documentation has improved a lot:
https://github.com/alipphardt/cdc-wonder-api/blob/master/CDC%2BWONDER%2BAPI%2BExample.ipynb
Here's how I think you can fix this:
xml_string = \
'''<query-parameters>
<parameter>
<name>stage</name>
<value>about</value>
</parameter>
<parameter>
<name>saved_id</name>
<value></value>
</parameter>
</query-parameters> '''
url = 'https://wonder.cdc.gov/controller/datarequest/D76' ## or D140
param_name = 'request_xml'
url = "https://wonder.cdc.gov/controller/datarequest/D76"
response = requests.post(url, data={"request_xml": xml_string, "accept_datause_restrictions": "true"})

Azure AD B2C - LookupValue fallback value

I am currently working on modifying a HRD policy to fit our needs. I have a claim 'domainParameter' that contains the email domain portion of the user login. I'm using a transform of LookupValue to map different domains. We have multiple groups who will be using our policy, some of which have multiple domains their users may sign up with. So our lookup shows something like the following:
<ClaimTransformation Id="GroupLookup" TransformationMethod="LookupValue">
<InputClaims>
<InputClaim ClaimTypeReferenceId="domainParameter" TransformationClaimType="inputParameterId" />
</InputClaims>
<InputParameters>
<InputParameter Id="company1.domain1" DataType="string" Value="company1" />
<InputParameter Id="company1.domain2" DataType="string" Value="company1" />
<InputParameter Id="company2.domain1" DataType="string" Value="company2" />
<InputParameter Id="errorOnFailedLookup" DataType="boolean" Value="false" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="domainGroup" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
This obviously works great when the domain is one of the listed domains, however we also want to allow local accounts to sign up/in and have them grouped into a group called "local", though name doesn't matter. From what I can find, I can't figure any way to have the claim assigned to a specific value if it fails the lookup. I can have it error on lookup by changing that parameter, but having it assign a value I see no way to do so. I have tried the DefaultValue attribute on 'domainGroup' both as an InputClaim and an OutputClaim, and neither work. I also see no option for wildcard selectors in the LookupValue.
Does anyone have a clue about how to get this done? I've scoured the documentation for a couple days now and have yet to find anything valuable.
The output is null for your claims transform when the lookup fails. No it cannot be set to something else directly, but can be indirectly:
I explain it in the sample how when the output of your claimsTransform is null, we do a Boolean comparison and the final value is FALSE for isKnownCustomer. That sends the user to the local account sign in page.
The capabilities of the transform are defined here
https://learn.microsoft.com/en-us/azure/active-directory-b2c/string-transformations#lookupvalue
The sample explains in detail how I get it do the logic you request. “ we also want to allow local accounts to sign up/in ... if it fails the lookup”
https://github.com/azure-ad-b2c/samples/blob/master/policies/home-realm-discovery-modern/readme.md
“The first step of the user journey presents a page to collect the users email address. The page uses input validation such that a valid email is provided.
The next step of the journey runs multiple output claims transforms to check if the domain is known.
First an output claims transformation called ParseDomain extracts the email domain name for the provided email address and copies it into the domainParameter claim.
Using the DomainLookup output claims transform, the domainParameter is looked up against a list of known domain names. If the domain name matches, DomainLookup will output a claim knownDomain = True, or otherwise it will be null.
To return a final True or False value for whether the domain was known, the CheckDomainParameterValue output claims transform is called, which compares the knownDomain with dummyTrue (which holds a True value inside it). Finally we obtain a claim isKnownCustomer which is either True or False. This prevents having a null value in the case of knownDomain.
Steps 3 and 4 handle the scenario where the domain was unknown, and mimic the steps to sign in via Local Account.”

Azure AD B2C: Extract single item from Json Array

I'm trying to extract a single email address from an array of email addresses (stored in the otherEmails attribute). I thought I could use the GetSingleValueFromJsonArray claims transformation. But, I get the following error:
The InputClaims mismatched in ClaimsTransformation with id
"GetEmailFromJson" with TransformationMethod
"GetSingleValueFromJsonArray". The following InputClaims were declared
in the Policy but were not expected by the TransformMethod:
[StringCollection]inputJsonClaim. The following InputClaims were
expected by the TransformMethod but were not declared in the Policy:
[String]inputJsonClaim.
It's complaining that my input is a collection of strings -which it is. The error says it wants a 'string' as input. The documentation also states that it wants a string. But then I'm confused how this should ever work with an array, as the name implies.
Essentially, I just want to return the email address in the id_token when using OpenID Connect. But with B2C it seems I can't set the mail field and it's null when I query for it. So, I've taken to using the otherEmails field. But I really only plan on storing a single email in it. Thus, I want to return the email claim as a single value claim, and not an array.
Update
After a bit more digging, I realized I can accomplish my goal without using a ClaimsTransformation. I can just map the 'signInNames.emailAddress' to 'email'.
<OutputClaim ClaimTypeReferenceId="signInNames.emailAddress" PartnerClaimType="email"/>
You can use the GetSingleItemFromStringCollection claims transformation to get the first item in the string collection.

Changing the Sort order on BDC Actions in SharePoint

We have a number of Actions defined in a BDC (Business Data Catalog) definition in SharePoint, and need to change the order they are displayed in the UI.
Within the Action defintion, there is a Position field, which we are specifying, however, the UI wants to display everything in Alphabetical order, which isn't what we are after.
An example of the Position section of the BDC Definition is shown below.
Do you know how this could be achieved successfully ?
<Action
Position="10"
IsOpenedInNewWindow="true"
Url="http://www.google.co.uk/search?q=%22{0}%22"
ImageUrl="/_layouts/1033/images/TAH/Google.gif"
Name="Google for Assured Name">
<ActionParameters>
<ActionParameter Index="0" Name="assured_name" />
</ActionParameters>
</Action>
(PS I did consider putting this on SuperUser, but there is no BDC there, and there are a number of BDC related questions on here, so here it is... ;) )
You could do through the naming of your actions, for example:
01 This is the first action
02 This is the second action
A bit of a hack, but it should work.
There is no MSDN documentation for the Position attribute other than verifying its existence (see Action documentation) but it seems reasonable to assume that it should do what you require.
I suspect that the lack of documentation is due to this feature not being fully implemented.
Something that may work is to add leading spaces in the Name attribute. If BDC does not strip these spaces automatically you could use it to cause the alphabetical ordering to do what you require (the more leading spaces you have, the further down the list the action will appear). When rendered as HTML the spaces will likely be stripped.

Resources