Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Client Credentials oauth flow for unsupervised clients #197

Open
DrPyser opened this issue Dec 13, 2021 · 10 comments
Open

Support Client Credentials oauth flow for unsupervised clients #197

DrPyser opened this issue Dec 13, 2021 · 10 comments

Comments

@DrPyser
Copy link

DrPyser commented Dec 13, 2021

We have scripts running as unsupervised background processes(as cronjobs). These scripts cannot rely on an interactive user consent flow for authentication. Previously we had been using the desktop flow to manually(through developer intervention on a local machine) retrieve an access and refresh token that were then copied over to the server side, which is obviously a problematic workflow for efficiency, reliability and security reasons.

Instead, I am trying to use the Client Credentials oauth flow which is designed for this purpose. Since we are part of the same entity owning the application and the bingads account which we are using with the API, we do not need explicit consent from a specific user(we are not acting on behalf of another user). we already possess the client credentials needed to authenticate.

I am trying to use tokens acquired through this flow using the microsoft service authentication library (https://github.com/AzureAD/microsoft-authentication-library-for-python). I am trying to implement a custom bingads.OAuthAuthorization subclass implementing this flow using the msal python library. Here's the code:

class OauthClientCredentialGrant(bingads.OAuthAuthorization):
    oauth_scopes = ["https://ads.microsoft.com/.default"]

    def __init__(self, client_id, msal_app: msal.ConfidentialClientApplication, environment: str):
        super(OauthClientCredentialGrant, self).__init__(
            client_id,
            env=environment,
            require_live_connect=False
        )
        self._msal_app = msal_app
        self.logger = logging.getLogger(f"{__name__}.{self.__class__.__name__}")

    def request_oauth_tokens(self) -> bingads.OAuthTokens:
        """
        request oauth tokens using the msal.ConfidentialClientApplication.
        Returns OauthToken containing access token(no refresh token)
        """
        response = self._msal_app.acquire_token_for_client(scopes=self.oauth_scopes)
        if "error" in response:
            self.logger.error("Error requesting access token through client credential flow")
            raise bingads.OAuthTokenRequestException(
                error_code=response["error_codes"][0],
                description=response["error_description"]
            )
        else:
            access_token = response["access_token"]
            expires_in = response["expires_in"]
            self._oauth_tokens = bingads.OAuthTokens(access_token=access_token, access_token_expires_in_seconds=expires_in, response_json=response)
            self.logger.info("Successfully obtained access token through client credential flow")

            return self.oauth_tokens

Acquiring the access token using msal works, but for some reason the bingads library still cannot successfully authenticate with the API.

Also, no refresh token are used in this flow.

Thanks!

@DrPyser DrPyser changed the title Support Client Credentials oauth flow for automated clients Support Client Credentials oauth flow for unsupervised clients Dec 13, 2021
@oaosman84
Copy link

Our team is having the same issue. We're also building a server-to-server flow with no third-party, and the standard interactive flow is not very feasible or secure. We'd love to be able to do a client_credentials flow but have been unable to get this to work.

@oaosman84
Copy link

It would be good to understand whether this is something the Ads API supports (in which case it's just a matter of getting the code working) or whether the API just doesn't support it at all and we have to use the standard flow w/ refresh tokens and such.

@qitia
Copy link
Collaborator

qitia commented Jan 12, 2022

to minimize dependency, bingads library does not use msal. I see you are using scope "https://ads.microsoft.com/.default", which is different from here, is that expected?

@oaosman84
Copy link

oaosman84 commented Jan 12, 2022

@qitia thanks! I've tried scope=https://ads.microsoft.com/msads.manage but get an error:

The provided value for scope https://ads.microsoft.com/msads.manage is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier

Sending scope=https://ads.microsoft.com/msads.manage/.default results in:

The resource principal named https://ads.microsoft.com/msads.manage was not found in the tenant named Microsoft Display Programmatic Direct. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant

I guess the question is whether we should expect the Ads API to support the client credentials flow or not

@ukankal
Copy link

ukankal commented Feb 3, 2022

Our team is facing the same issue as described by @oaosman84.

I guess the question is whether we should expect the Ads API to support the client credentials flow or not

@qitia - could you please confirm on this?

@Luttik
Copy link

Luttik commented Mar 21, 2022

This is quite an elementary and fundamentally essential feature for most use-cases for any api. Can you guys confirm or deny if this works for the reporting API (i.e. that having a headless / unsupervised service is even possible)?

@pep4eto1211
Copy link

Has there been any update on that? I've recently had to deal with the LinkedIn API, which also doesn't allow for client_credentials flow for ad analytics, so I don't have high hopes. However, if anyone had managed to find something, please share.
In addition the auth page in the docs now shows a message that says that all API usage will require 2FA, which doesn't look promising:
image

@oaosman84
Copy link

We had to eliminate our spend on the Bing Ads platform and shift that budget to other platforms since the current API flow is untenable for us.

@shalakhin
Copy link

shalakhin commented Aug 29, 2022

Microsoft does a bad job as always. No answers, no docs, no convenient API just that SOAP crap that thousands of developers have to deal with

@npt-dev
Copy link

npt-dev commented Oct 19, 2023

It's been 2 years and there hasn't been any further interest from Microsoft. I think it's not difficult to explain why Bing is rated so low by users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants