You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm raising this as a discussion rather than an issue as this area is complicated and there is a reasonable chance I've misunderstood the nuances of resource and scope in relation to Entra ID and the relevant OAuth flows. However, it looks like there may be some possible changes to the subset of flows relating to client credentials to reduce the potential for errors, primary by only allowing a single scope/resource rather than multiple. I understand that this may be hard to do at the TokenCredential::get_token level as this has to handle flows where it is plausible that multiple scopes may be passed, and the user of get_token is unaware of the actual flow that will be used to get the token.
One possible option could be an API that separates out the resource and scopes, such that implementors of TokenCredential can choose to just ignore the scopes and instead apply /.default where that is the correct course of action. To make it work with the existing API, implementers that require /.default only would need to first parse the first scope, extract only the valid resource part, and then append /.default as required. By separating the resource and scopes, it opens the possibility for the resource to eventually be provided via an enum that contains the common services (blob, AzureSQL, etc) and a custom option for other cases.
/// Represents a credential capable of providing an OAuth token.#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]pubtraitTokenCredential:Send + Sync + Debug{/// Gets a `AccessToken` for the specified resourceasyncfnget_token(&self,resource:&str,scopes:&[&str]) -> crate::Result<AccessToken>;/// Clear the credential's cache.asyncfnclear_cache(&self) -> crate::Result<()>;}
I'd noticed that in the recent changes in #1493 (specifically, to TokenCredential::get_token), it is now possible to pass multiple scopes when requesting a new (or cached) token.
However, attempting to get a token for multiple scopes, I get the following error:
a) When using Graph scopes, eg User.Read / Groups.Read.All, these are not valid when using Client credential style flows:
[2024-01-05T04:19:31Z ERROR azure_identity::federated_credentials_flow] rsp_body == "{\"error\":\"invalid_scope\",\"error_description\":\"AADSTS1002012: The provided value for scope https://graph.microsoft.com/User.Read is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI). Trace ID: 91450bbd-f372-49df-a96a-a6a5208a4501 Correlation ID: ddf3f914-1029-4a97-8fbd-4ad9cf58a940 Timestamp: 2024-01-05 04:19:31Z\",\"error_codes\":[1002012],\"timestamp\":\"2024-01-05 04:19:31Z\",\"trace_id\":\"91450bbd-f372-49df-a96a-a6a5208a4501\",\"correlation_id\":\"ddf3f914-1029-4a97-8fbd-4ad9cf58a940\"}"
b) When using multiple /.default scopes, but for the exact same resource
[2024-01-05T04:20:24Z ERROR azure_identity::federated_credentials_flow] rsp_body == "{\"error\":\"invalid_scope\",\"error_description\":\"AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope https://graph.microsoft.com/.default https://graph.microsoft.com/.default is not valid. Trace ID: 648a359c-04e3-41c3-95c6-6e9a449d7001 Correlation ID: e74ff3d0-90a0-4d24-beb6-7f0b868f0f06 Timestamp: 2024-01-05 04:20:24Z\",\"error_codes\":[70011],\"timestamp\":\"2024-01-05 04:20:24Z\",\"trace_id\":\"648a359c-04e3-41c3-95c6-6e9a449d7001\",\"correlation_id\":\"e74ff3d0-90a0-4d24-beb6-7f0b868f0f06\"}"
In my specific case I'm using the federated_credentials_flow - which has had a scopes: &[&str] argument since implementation, but from what I can discern from the documentation allows multiple scopes, only when they are for the same resource, but this conflicts with the requirement to always use the /.default suffix, meaning that the slice must always have exactly one element.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I'm raising this as a discussion rather than an issue as this area is complicated and there is a reasonable chance I've misunderstood the nuances of
resource
andscope
in relation to Entra ID and the relevant OAuth flows. However, it looks like there may be some possible changes to the subset of flows relating to client credentials to reduce the potential for errors, primary by only allowing a single scope/resource rather than multiple. I understand that this may be hard to do at theTokenCredential::get_token
level as this has to handle flows where it is plausible that multiple scopes may be passed, and the user ofget_token
is unaware of the actual flow that will be used to get the token.One possible option could be an API that separates out the resource and scopes, such that implementors of
TokenCredential
can choose to just ignore the scopes and instead apply/.default
where that is the correct course of action. To make it work with the existing API, implementers that require/.default
only would need to first parse the first scope, extract only the valid resource part, and then append/.default
as required. By separating the resource and scopes, it opens the possibility for the resource to eventually be provided via anenum
that contains the common services (blob, AzureSQL, etc) and a custom option for other cases.I'd noticed that in the recent changes in #1493 (specifically, to
TokenCredential::get_token
), it is now possible to pass multiple scopes when requesting a new (or cached) token.However, attempting to get a token for multiple scopes, I get the following error:
a) When using Graph scopes, eg User.Read / Groups.Read.All, these are not valid when using Client credential style flows:
b) When using multiple
/.default
scopes, but for the exact same resourceIn my specific case I'm using the
federated_credentials_flow
- which has had ascopes: &[&str]
argument since implementation, but from what I can discern from the documentation allows multiple scopes, only when they are for the same resource, but this conflicts with the requirement to always use the/.default
suffix, meaning that the slice must always have exactly one element.Beta Was this translation helpful? Give feedback.
All reactions