Repository navigation
[Feature Request] Ability to use the Application URI as the client_id in PublicClientApplication #806
Description
Activity
By design, an app's client_id is its canonical identifier. The Application URI, on the contrary, might not even be established, or likely has a shape as
api://{your_client_id}which isn't more readable than client_id.Not sure how your downstream developer got their application uri
https://devcon1.cloud.igloo.wtwsaas.dev/. But if they know how to set a new application uri, they shall be able to also find the client_id, perhaps with some FAQ with screenshot from your side?While we may evaluate this feature request in the future, the suggestion for you is to stick with client_id whenever possible.
Hi, thanks for the quick response. In our case the Application URI is set up when we deploy the Igloo Cloud environment and is deliberately set to the domain name of the URL hosting the environment. This is very useful as it allows our Clients to connect to the Igloo Cloud OData feed using Excel and Power BI without the need for any additional information except for the OData feed URL itself.
We would like to support a similar ease of use for our Python connector, where all the Python developer needs to know is the URL to the Igloo Cloud API service.
As it stands they need both the URL and the Client Id of the Enterprise Application. Obviously this is not a show stopper and we have been supporting this set up for a while now, however it does cause our users some friction. I'd love to see the msal library support this use case if it is simple to achieve.As an aside, when I removed the lines:
if client_id: valid_aud = client_id in decoded["aud"] if isinstance( decoded["aud"], list) else client_id == decoded["aud"] if not valid_aud: raise IdTokenAudienceError( "3. The aud (audience) claim must contain this client's client_id " '"%s", case-sensitively. Was your client_id in wrong casing?' # Some IdP accepts wrong casing request but issues right casing IDT % client_id, _now, decoded)from oidc.py the device code flow completed successfully and I can connect to the Igloo Cloud API.
I gave it more thought, but still not quite sure that this client-side SDK (MSAL) shall remove that check broadly. Quoting from the OIDC specs, section 3.1.3.7. ID Token Validation:
Clients MUST validate the ID Token in the Token Response in the following manner:
...
3. The Client MUST validate that the aud (audience) Claim contains its client_id value registered at the Issuer identified by the iss (issuer) Claim as an audience. The aud (audience) Claim MAY contain an array with more than one element. The ID Token MUST be rejected if the ID Token does not list the Client as a valid audience, or if it contains additional audiences not trusted by the Client.I can understand your scenario, Adrian Peck (@BertieWTW) . Perhaps you may consider the following two alternatives.
- Given that the Entra ID accepts Application URI as if a client id, yet issues an ID token whose
audclaim has currently only the real client id, you may explore getting help from Entra ID to see if Entra ID shall issue ID tokens withaudclaims containing both client id and Application URI. That feels like the right solution. - Meanwhile, you may fork this client-side SDK and remove that check by yourself.
- Given that the Entra ID accepts Application URI as if a client id, yet issues an ID token whose
- Many thanks for your help with this issue. My thinking was that there was no particular need for this part of the msal library to validate the claims as the purpose of this call is simply to retrieve the bearer token which the python application will pass on the relevant web service which will need to validate the bearer token before servicing any API calls. However I am by no means an expert in this area, so would definitely expect you to seek advice before making any changes !
... there was no particular need for this part of the msal library to validate the claims as the purpose of this call is simply to retrieve the bearer token which the python application will pass on the relevant web service
That part is debatable.
There are two layers here.
- The underlying OAuth2 protocol is used to obtain an access token (colloquially known as a "bearer token" although that is not a precise term).
- The OpenID Connect protocol which is defined on top of OAuth2 to also obtain an ID token alongside with the access token.
Your scenario may need
#1only, but MSAL library is implemented at#2level, therefore the ID token validation is conceptually relevant.For the sake of completeness, this MSAL Python library does contain an OAuth2-only component, which can be used to obtain an access token without any ID token validation, but it is NOT part of MSAL Python's official API so it might be changed without prior notice. Besides, using such a low-level building block would also mean that you won't have MSAL's token cache benefit.
So, realistically speaking, I still think your best bet is the two options that I mentioned in my previous message.
- Understood, thanks for the detailed explanation.
- locked and limited conversation to collaborators
on Jun 6, 2025
MSAL client type
Public
Problem Statement
We have written a python package (wtwco-igloo on PyPi) that allows our users to use Python to connect to their Igloo Cloud environment that is secured with Entra Id. One form of authentication that we support uses the device code flow to allow the user to interactively supply their user credentials to log in to the Enterprise Application as themselves.
However in order for this to work they need to configure wtwco-igloo to use the correct client_id for their Enterprise Application which causes lots of support issues for us.
It would be much nicer if instead of the user having to find the correct client_id, the wtwco-igloo package could instead use the Application URI of the Enterprise Application which, in our case, is simply the domain name of the URL of the Igloo Cloud API.
This is, for instance, how the Excel OData feature authenticates to our Igloo Cloud environment without requiring the user to know what the client_id is.
The frustrating thing is that this msal package is really close to allowing this feature to work, however there is a check in decode_id_token() that checks that the audience claim in the token retrieved from Entra Id is equal to the client_id passed in to the PublicClientApplication. However this won't be the case when the Application URI is used as the Client Id of the Enterprise Application is returned in the token.
See below for a simple example that I would like to work but which raises the error:
IdTokenAudienceError(
msal.oauth2cli.oidc.IdTokenAudienceError: 3. The aud (audience) claim must contain this client's client_id "https://devcon1.cloud.igloo.wtwsaas.dev", case-sensitively. Was your client_id in wrong casing? Current epoch = 2025-04-11 15:41:46. The id_token was approximately: {
"aud": "f5f74c0d-fdd2-473d-b46d-0066c0ee23a9",
"iss":
...
It might be that you consider this issue to be more of a bug than a feature request, I wasn't too sure.
Many thanks,
Bertie
Proposed solution
I would like the following code to work (you will obviously need to use a different application_uri to match an Enterprise Application that you have access to)
import requests
from msal import PublicClientApplication
application_uri = "https://devcon1.cloud.igloo.wtwsaas.dev"
scope = f"{application_uri}/user_impersonation"
authority = "https://login.microsoftonline.com/organizations"
http_client = requests.Session()
msal_client = PublicClientApplication(client_id=application_uri, authority=authority, http_client=http_client)
flow = msal_client.initiate_device_flow(scopes=[scope])
print(flow["message"])
result = msal_client.acquire_token_by_device_flow(flow)