3

I am trying to get the groups that a certain user belongs to in their sign-in journey.

I am using calling RESTful graph API for that.

Here are my Technical Profiles, the idea is to get token for my graph API app and use the token to do a /getMemberGroups call to get the groups as StringCollection:

<ClaimsProvider>
    <DisplayName>Get user groups of a certain user</DisplayName>
    <TechnicalProfiles>
      <TechnicalProfile Id="GetAccessTokenForGraphApi">
        <DisplayName></DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
          <Item Key="ServiceUrl">https://login.microsoftonline.com/{tenant_name}.onmicrosoft.com/oauth2/v2.0/token</Item>
          <Item Key="AuthenticationType">Basic</Item>
          <Item Key="SendClaimsIn">Form</Item>
        </Metadata>
        <CryptographicKeys>
          <Key Id="BasicAuthenticationUsername" StorageReferenceId="B2C_1A_userMgntAppId" />
          <Key Id="BasicAuthenticationPassword" StorageReferenceId="B2C_1A_userMgntAppClientSecret" />
        </CryptographicKeys>
        <InputClaims>
          <InputClaim ClaimTypeReferenceId="grant_type" DefaultValue="client_credentials" />
          <InputClaim ClaimTypeReferenceId="scope" DefaultValue="https://graph.microsoft.com/.default" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="bearerToken" PartnerClaimType="access_token" />
        </OutputClaims>
        <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
      </TechnicalProfile>
      <TechnicalProfile Id="GetUserGroups">
        <DisplayName>Retrieves security groups assigned to the user</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
          <Item Key="ServiceUrl">https://graph.microsoft.com/v1.0/users/{objectId}/getMemberGroups</Item>
          <Item Key="AuthenticationType">Bearer</Item>
          <Item Key="UseClaimAsBearerToken">bearerToken</Item>
          <Item Key="SendClaimsIn">Body</Item>
          <Item Key="AllowInsecureAuthInProduction">true</Item>
          <Item Key="ClaimUsedForRequestPayload">securityEnabledOnly</Item>
          <Item Key="DefaultUserMessageIfRequestFailed">Cannot process your request right now, please try again later.</Item>
        </Metadata>
        <InputClaims>
          <InputClaim Required="true" ClaimTypeReferenceId="objectId" />
          <InputClaim Required="true" ClaimTypeReferenceId="bearerToken" />
          <InputClaim Required="true" ClaimTypeReferenceId="securityEnabledOnly" DefaultValue="false" AlwaysUseDefaultValue="true" />
        </InputClaims>
        <OutputClaims>
          <OutputClaim ClaimTypeReferenceId="groups" PartnerClaimType="value" />
        </OutputClaims>
        <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
      </TechnicalProfile>
    </TechnicalProfiles>
  </ClaimsProvider>

The GetAccessTokenForGraphApi TP is working fine and I can get the bearerToken output claim if I call it solely in my userJourney.

However, when I put GetUserGroups TP as next orchestration step, I have this sort of exception in my application insight log:

{
    "Kind": "HandlerResult",
    "Content": {
      "Result": true,
      "RecorderRecord": {
        "Values": [
          {
            "Key": "SendErrorTechnicalProfile",
            "Value": "OpenIdConnectProtocolProvider"
          },
          {
            "Key": "Exception",
            "Value": {
              "Kind": "Handled",
              "HResult": "80131500",
              "Message": "Cannot process your request right now, please try again later.",
              "Data": {
                "IsPolicySpecificError": false
              },
              "Exception": {
                "Kind": "Handled",
                "HResult": "80131500",
                "Message": "Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details.",
                "Data": {}
              }
            }
          }
        ]
      },

I believe there is some error when calling the RESTful endpoint. My question is, how I can "visualize" the restful call to see what I actually send out? For example, as you can see I am putting objectId in my URL, seeing the actual URL would be useful to troubleshoot the restful call.

Kindly let me know if more information I need to supplement. Many thanks in advance!

ray
  • 11,310
  • 7
  • 18
  • 42
  • https://stackoverflow.com/questions/54875609/calling-the-azure-ad-graph-api-from-an-azure-ad-b2c-custom-policy Dynamic Urls can be supported in Restful Provider with the metadata key "SendClaimsAs" = "Url" – Saravana Kumar Jan 13 '21 at 10:32
  • 1
    Hi @Ray. I don't believe that the Application Insights entries contain the request URL. What if you change the request hostname from `graph.microsoft.com` to [a ngrok tunnel](https://ngrok.com/) temporarily to test the request URL. BTW, I don't believe that you can include a claim value (e.g. `objectId`) for a POST operation in the request URL, but nonetheless you might want to try to add `{Claim:objectId}` to the request URL and add [the `IncludeClaimResolvingInClaimsHandling` metadata](https://docs.microsoft.com/en-us/azure/active-directory-b2c/claim-resolver-overview#using-claim-resolvers). – Chris Padgett Jan 13 '21 at 10:35
  • Hi @SaravanaKumar, thanks for your help first:) I am aware of the SendClaimsAs Option but then I lost the ability to send the `securityEnabledOnly` JSON body, which is [required](https://learn.microsoft.com/en-us/graph/api/user-getmemberobjects?view=graph-rest-1.0&tabs=http#request-body) by the graph API call. – ray Jan 13 '21 at 11:19
  • Hi @ChrisPadgett, thanks for your help :) I doubt that I am not even sending to correct URL.. Your ngrok tunnel suggestion looks promising and I will try that. From my google research result, it looks like all working examples are wrapping that graph API call with another API to help trigger the RESTful call and bypass the syntax limitation in ADB2C custom policy. – ray Jan 13 '21 at 11:22

1 Answers1

1

You can't do this: <Item Key="ServiceUrl">https://graph.microsoft.com/v1.0/users/{objectId}/getMemberGroups</Item>

And this in combination: <Item Key="SendClaimsIn">Body</Item>

You can either send claims in URL, where your claim resolver will resolve the objectId, or you send claims in body. https://learn.microsoft.com/en-us/azure/active-directory-b2c/restful-technical-profile#metadata

That is why your call fails.

You need to call your own API, and then have your own API call Graph API.

Jas Suri - MSFT
  • 10,605
  • 2
  • 10
  • 20