0
votes

Referring to this page: https://docs.microsoft.com/en-us/azure/api-management/policies/send-request-context-info-to-backend-service

I am trying to get the User.Group using a policy such that I can restrict access to CRUD operations based on membership of 'read-only' or 'full-access' group.

All of the Microsoft Docs state that you can get user context by accessing @(context.User) and then whatever property you want. My proposed policy was this:

<policies>
    <inbound>
        <rewrite-uri template="/views/foo" />
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <choose>
            <when condition="@(context.User.Groups.Select(g => g.Name).Contains("Read-Only-Group"))">
                <return-response>
                    <set-status code="403" reason="Unauthorized" />
                    <set-body>You do not have write access - this operation is not available</set-body>
                </return-response>
            </when>
        </choose>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

The problem I am having is that whichever basic examples I try and implement in policy, I am getting "Error 500 - Object not set to an instance of object" whenever I try and get anything to do with the User. I understand this means my User object is not populated, but I don't get why.

Even if I refer to the basic examples on the Microsoft page to set some headers containing the Product name and User ID, they fail with the same error. Those pages don't contain any info on additional steps needed to access the User object.

How can I access these items?

1
Did you make the API so that subscription is required and you also pass a subscription key? Otherwise APIM would not be able to refer to an user object.Kai Walter
All of my APIs require subscription, and I’m passing in a subscription key as a header. Debugging with VScode shows the user object is always nullDamoven

1 Answers

0
votes

I used https://reqbin.com/echo/get/json as a mock backend and this API operation policy:

<policies>
    <inbound>
        <rewrite-uri template="/echo/get/json" />
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <choose>
            <when condition="@(context.User.Groups.Select(g => g.Name).Contains("Developers"))">
                <return-response>
                    <set-status code="403" reason="Unauthorized" />
                    <set-body>You do not have write access - this operation is not available</set-body>
                </return-response>
            </when>
        </choose>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

I set the API to subscription required.

When running an operation with a subscription key of a product valid for the API, I get the correct response (as everybody is in group Developers by default):

You do not have write access - this operation is not available

Then unchecking subscription required and running the operation without a subscription key gives me:

{
  "statusCode": 500,
  "message": "Internal server error",
  "activityId": "46600c4a-960a-479e-a634-8e2857cea512"
}

Hence, when you want to access context.User object, you need to work with an API which has subscription required.