Shaun Ryan
Shaun Ryan

Reputation: 1728

What is the Azure MSAL Scope for Authenticating Service Principal to Run a Data Factory pipeline?

I'm just trying to wrap some python around the REST API call to run a data factory pipeline using the REST API pipeline create-run

I'm using the MSAL python library to authenticate the service principal and get a token which works fine but I'm getting a 401 calling the endpoint.

https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DataFactory/factories/{factoryName}/pipelines/{pipelineName}/createRun?api-version=2018-06-01

The service principal is an app registration authenticated with a secret. The service principal has DataFactory Contributor role. Getting the token works fine. However I think it's because this scope is wrong?

result = app.acquire_token_for_client(
scopes=["https://graph.microsoft.com/.default"]
)

Where on earth are the scopes documented for calling the relevant services, can't find it anywhere.

class MsalAuth(Auth):
    def __init__(self, parameters: dict):


        self.sp_client_id = parameters["sp_client_id"]
        self.sp_client_secret = parameters["sp_client_secret"]
        self.tenant_id = parameters["tenant_id"]
        authority = f"https://{_AUTH_DNS}/{self.tenant_id}"

        app = msal.ConfidentialClientApplication(
            self.sp_client_id,
            authority=authority,
            client_credential=self.sp_client_secret
        )
        result = app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"])
        self.bearer_token = result['access_token']

    def get_headers(self):
        headers = {"Authorization": f"Bearer {self.bearer_token}"}
        return headers

This exception is thrown when call the create run api end point. Note url is redacted with question marks to prevent exposing resource identifiers:

Exception has occurred: DataFactoryPipelineException
Failed on pipeline name=test
  File "/Users/shaunryan/autopipes/autopipes/data_factory.py", line 30, in pipeline_create_run
    response = _api_service.api_post(endpoint)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/shaunryan/autopipes/autopipes/api_service/api_service.py", line 146, in api_post
    response = _base_api_post(url=url, headers=self._headers, json=data)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/shaunryan/autopipes/autopipes/api_service/_base_api.py", line 93, in base_api_post
    raise e
  File "/Users/shaunryan/autopipes/autopipes/api_service/_base_api.py", line 88, in base_api_post
    response.raise_for_status()
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://management.azure.com/subscriptions/000000-00000-00000-?????-???????/resourceGroups/?????????/providers/Microsoft.DataFactory/factories/????????/pipelines/test/createRun?api-version=2018-06-01

I've tried search all over for the scope to use for data factory but I can't find it.

Upvotes: 0

Views: 135

Answers (1)

Shaun Ryan
Shaun Ryan

Reputation: 1728

As always spend all day on an issue, I post a question then figure out the answer in the next 2 minutes!

The scope is this because it's the https://management.azure.com/.default because that's the host on the api I'm calling!

I also had to assign the registered app (service principal) access to the api in the portal.

Worked fine afterwards.

Upvotes: 0

Related Questions