-
Notifications
You must be signed in to change notification settings - Fork 797
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 Oauth Code Flow #22818
Comments
Can you please add some more details about what you're trying to do and the change you would like to see? |
Hi @denen99. Thank you for opening this issue and giving us the opportunity to assist. To help our team better understand your issue and the details of your scenario please provide a response to the question asked above or the information requested above. This will help us more accurately address your issue. |
Hi Charles -
I have an Azure App I am building that will be used for clients of various
MS Tenants to Oauth and give permission to in order for us to scan their
onedrive in the background. To do this, we are using the auth code flow (
https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow),
the user gives consent for the delegated permissions (File.Read,
File.Read.All and offline_access), we get a code and we exchange that code
for an access and refresh token.
Now on our backend, we want to instantiate an Azure SDK Client for our
application using azidentity, but my understanding is this flow is not
supported in the Azure SDK for Go. azidentity.NewClientSecretCredential
seems to not be intended for delegated permissions, only app permissions
and my understanding is creating a client with this flow is not supported.
Once we have a credential object, we want to pass that to the msgraphsdk Go
library so that we can query the various users OneDrive folder contents.
Does that make sense? I could be misunderstanding but none of the existing
New[FOO]Credential methods seemed to support this flow, perhaps I am
missing something. I tried DeviceCode and ClientSecret and neither of them
worked without errors.
Thank you !
Adam
…On Wed, May 1, 2024 at 6:32 PM Charles Lowell ***@***.***> wrote:
Can you please add some more details about what you're trying to do and
the change you would like to see?
—
Reply to this email directly, view it on GitHub
<#22818 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAA7J577WULQ4QYXOWQ73BLZAFUOXAVCNFSM6AAAAABHCSCGSGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOBZGIZTQNZZGM>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
You're right that ClientSecretCredential isn't for delegation. You would use it when you want your app to access resources as itself. It sounds like you want Entra's on-behalf-of flow instead, documented here. A user would authenticate to your app, which would then exchange the user's access token for one allowing it to access resources on that user's behalf. Does that sound like what you're looking for? azidentity.OnBehalfOfCredential implements it. |
Hi @denen99. Thank you for opening this issue and giving us the opportunity to assist. To help our team better understand your issue and the details of your scenario please provide a response to the question asked above or the information requested above. This will help us more accurately address your issue. |
What should the value of userAssertion be in that method, is it the accessToken? If so, is it expected that the refresh_token is used to get an updated access_token via a different method? here is my code:
But its throwing the following error (it works fine when using the HTTP URL raw) Error getting drive: OnBehalfOfCredential authentication failed POST https://login.microsoftonline.com/common/oauth2/v2.0/tokenRESPONSE 400 Bad Request{ |
Your code looks right to me though I'm not familiar with Graph or its SDK, so I may miss something there. |
Hi @denen99. Thank you for opening this issue and giving us the opportunity to assist. To help our team better understand your issue and the details of your scenario please provide a response to the question asked above or the information requested above. This will help us more accurately address your issue. |
Yes I believe the format of UserAssertion is what's wrong here but there is
no way to figure out why.
This is the JSON returned from the /authorize endpoint when exchangin a
Code for a token via the Oauth Code flow , i am using the value of the
"access_token" field. There is no place to put the refresh_token which is
why I was curious as to how this was handled automatically? Perhaps I am
missing some detail on the structure of the UserAssertion string? Is there
a method to construct this correctly? Its tricky if its a string and not a
type/struct
{
"access_token": "REDACTED",
"refresh_token": "REDACTED,
"scope": "Files.Read Files.Read.All Files.Read.Selected User.Read profile
openid email",
"expires_in": 5227,
"token_type": "Bearer"
}
…On Thu, May 2, 2024 at 1:29 PM Charles Lowell ***@***.***> wrote:
Your code looks right to me though I'm not familiar with Graph or its SDK,
so I may miss something there. userAssertion is the user's access token
for your app. OnBehalfOfCredential handles the details of refreshing
internally, redeeming the refresh token as needed. I suppose the error must
be about the value of userAssertion because that becomes the assertion
parameter of your app's token request. I haven't seen this error before but
it's saying the signature on userAssertion doesn't verify. Is the value
the user's access token for your app?
—
Reply to this email directly, view it on GitHub
<#22818 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAA7J53IAHWNGSAAWXF7LCLZAJZWJAVCNFSM6AAAAABHCSCGSGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJRGEZDIMBUHA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
refresh_token is for the user to acquire other access tokens and isn't relevant to delegation. |
Understood. That is exactly what I am doing though.
User goes through the Oauth code flow, redirects to my app with a ?code,
query param. I then exchange that code for an acess_token , and securely
store the access_token and refresh_token in my backend.
Then I load that access_token, pass it into the NewOnBehalf.. method as I
pasted but it still returns the same error. Not sure what you mean that
the access_token is for Graph? Its the access_token returned via the Oauth
Code Flow for the user and is what is passed to the UserAssertion parameter.
Sorry if I am missing something obvious here
…On Thu, May 2, 2024 at 4:19 PM Charles Lowell ***@***.***> wrote:
refresh_token is for the user to acquire other access tokens and isn't
relevant to delegation. userAssertion would be the value of access_token.
However, I see from the scopes that this access token is for Graph? It
should be for your app (i.e., have your app as its audience), not the
upstream resource you want the user to delegate access to. In this protocol
diagram
<https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow#protocol-diagram>,
your application is "Web API A" and Graph is "Web API B". The user acquires
an access token for your app and presents it to your app e.g. as part of
some HTTP request. That's step 1. OnBehalfOfCredential handles steps 2 and
3; the user's access token for your app is its userAssertion.
—
Reply to this email directly, view it on GitHub
<#22818 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAA7J53HTQGBBOS5UZLD4KDZAKNVTAVCNFSM6AAAAABHCSCGSGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJRGQ4DKNZSGY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
No worries, this is a confusing scenario. In your last comment you shared what looks like the body of a response to an authentication request. The "scope" field documents what the access token is for. Those look like Graph scopes to me. If they are, the token is for accessing Graph, not your application, and you couldn't use it for delegation. What scopes do you request in the auth code flow? |
Sorry i figured this was a standard use case where a refresh_token is
persisted on the backend and then used to query services on behalf of a
user when getting an updated access_token
The flow is initiated with this URL for Files.Read, Files.Read.All and
offline_access (for the refresh_token)
https://login.microsoftonline.com/MY_TENANT_ID/oauth2/v2.0/authorize
<https://login.microsoftonline.com/68de924b-91e1-40fa-a91c-778efb633fff/oauth2/v2.0/authorize>
?client_id=MY_APP_CLIENT_ID&scope=
<https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=%7Bclient_id%7D&scope=%7Bscope%7D>
files.read%20files.read.all%20offline_access&response_type=code&redirect_uri=
http://localhost:8080/oauth/msft_callback
That redirects back to
http://localhost:8080/oauth/msft_callback?code=[authorization_code] , i
then POST to "https://login.microsoftonline.com/common/oauth2/v2.0/token"
with the following params to get that JSON payload back which has
access_token and refresh_token with token of type Bearer
formData := url.Values{
"grant_type": {"authorization_code"},
"client_id": {client_id},
"client_secret": {client_secret},
"redirect_uri": {redirect_uri},
"code": {authorizationCode},
}
From the returned json i use the value of access_token to pass to the
NewOnBehalfOfUser param
My goal is to have a backend application that runs every 15 minutes, uses
the refresh_token to get a new access_token, and then queries the users
OneDrive with the msgraphsdk, but the msgraphsdk requires a cred parameter
that has me stuck here on how to properly construct from azidentity
…On Thu, May 2, 2024 at 4:57 PM Charles Lowell ***@***.***> wrote:
No worries, this is a confusing scenario. In your last comment you shared
what looks like the body of a response to an authentication request. The
"scope" field documents what the access token is for. Those look like Graph
scopes to me. If they are, the token is for accessing Graph, not your
application, and you couldn't use it for delegation. What scopes do you
request in the auth code flow?
—
Reply to this email directly, view it on GitHub
<#22818 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAA7J56TPXCXW5TTDS2FYSDZAKSCTAVCNFSM6AAAAABHCSCGSGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJRGU2TIMZRGM>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
I'm sorry, I assumed your app runs on a server, but I notice you're redirecting to localhost with the authorization code. Does your app run on a user's machine? |
No purely server based. http://localhost:8080 was just bc i was testing
locally.
Frontend app redirects to msft login url, user authorizes app, MSFT
redirects to redirect_uri with ?code, i exchange code for token and store
token securely
…On Thu, May 9, 2024 at 8:19 PM Charles Lowell ***@***.***> wrote:
I'm sorry, I assumed your app runs on a server, but I notice you're
redirecting to localhost with the authorization code. Does your app run on
a user's machine?
—
Reply to this email directly, view it on GitHub
<#22818 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAA7J54MX6WUWXX24SS6ZPLZBQG7NAVCNFSM6AAAAABHCSCGSGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMBTGYZTOMJSGI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Got it, thanks for clarifying. I asked about this because client apps should use a different solution. Returning to authorization code vs. on-behalf-of (OBO), one key difference is that OBO separates a user's authorization to access an app from that app's authorization to access other APIs. In your case this means OBO would separate a user's authorization to access your app from your app's authorization to access Graph on that user's behalf. In the OBO flow a user would acquire an access token for your app, not for Graph, and your app would later exchange that token for an access token for Graph. |
Feature Request
The text was updated successfully, but these errors were encountered: