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.”
Related
I am trying to pass {Culture:LanguageName} and {OAUTH-KV:key} to json body in post request using GenerateJson transfomration method. Unfortunately I am not able to pass it to json, both values are resolved to value "undefined" and skipped during json generation. I managed to make it work but only with
<UserInputType>Readonly</UserInputType>
in claim type.
I don't want to display those values in UI form so leaving readonly input type is not an option for me.
added two ClaimType for each param I want to include in my json
Setup another technical profile with <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item> metadata and included AlwaysUseDefaultValue="true" DefaultValue="{Culture:LanguageName}" in InputClaim
used it in my user journey as first step with ClaimsExchange
Used claims setup in first step in my json transformation
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.
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"})
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.
If the same output claim is defined in multiple technical profiles, what is the expected behavior?
Particularly if a technical profile emits an output claim and another technical profile that executes later defines the same output claim but does not emit one at run time, what is the expected behavior?
If there are two different OrchestrationSteps, each containing a TechnicalProfile that emits the same claim, then the TechnicalProfile from the later step will "overwrite" the value of the claim if such a claim is emitted.
Lets take a specific (although somewhat made-up) example.
Step 1 uses a TechnicalProfile for a SelfAsserted page that asks the user for their first name via "OutputClaim ClaimTypeReferenceId="givenName"" . The user fills in the name "John" on this page, and continues.
Step 2 uses a TechnicalProfile for a ClaimsExchange with Google, which may also emit a first name via "OutputClaim ClaimTypeReferenceId="givenName"".
However, it is possible that the user did or did not register their first name when creating their account at Google. If the first name is available (lets say with the name "Lingeshwaran"), then Google will emit that claim, and B2C will consume it. In this case, the final resulting value after step 2 for givenName will be "Lingeshwaran".
If the user did not fill in their first name when creating their Google account, then it will be missing from the claims that Google emits in their token. As a result, the existing "givenName" claim will not be overwritten, and the resulting value after step 2 for givenName will be "John".