I am seeing callback URL for DocuSign Oauth gets updated after I submit my email on DocuSign login page.
This is the URL for my OAuth flow which takes user to the DocuSign (sandbox) Login page.
https://account-d.docusign.com/oauth/auth?response_type=code&client_id=REST-41b3bb1d-94dc-44e3-b791-4810407b961d&scope=all&redirect_uri=https://localhost&state=https://localhost2/super/fx/oauth-callback.flex?osp=29cad06bee24300015fc6c67f95808d2%26intsys%3Dfe7a908b327570000b21578fac28005b#/username
Notice that the callback URL has a "osp" variable but it gets stripped away after email submission.
https://account-d.docusign.com/username?response_type=code&client_id=REST-41b3bb1d-94dc-44e3-b791-4810407b961d&scope=all&redirect_uri=https%3A%2F%2Flocalhost%2Fcb1&state=https%3A%2F%2Flocalhost2%2Fsuper%2Ffx%2Foauth-callback.flex%3Fosp#/password
Re:
I want to get some insight on why the 'osp' variable was stripped away in the URL in the process of OAuth flow and how we can prevent it. It seems to me that DocuSign encodes the URL once a user submits their email, would this issue be related to this encoding process?
In the OP, url being sent to DocuSign's OAuth service is:
https://account-d.docusign.com/oauth/auth?response_type=code&client_id=REST-41b3bb1d-94dc-44e3-b791-4810407b961d&scope=all&redirect_uri=https://localhost&state=https://localhost2/super/fx/oauth-callback.flex?osp=29cad06bee24300015fc6c67f95808d2%26intsys%3Dfe7a908b327570000b21578fac28005b#/username
Let's pull it apart:
response_type=code
client_id=REST-41b3bb1d-94dc-44e3-b791-4810407b961d
scope=all
redirect_uri=https://localhost
state=https://localhost2/super/fx/oauth-callback.flex?osp=29cad06bee24300015fc6c67f95808d2%26intsys%3Dfe7a908b327570000b21578fac28005b#/username
So it is not the case that the osp value is being included with the redirect uri. It is being included with the state query parameter.
You should instead send
response_type=code&client_id=REST-41b3bb1d-94dc-44e3-b791-4810407b961d&scope=all&redirect_uri=https://localhost?osp=29cad06bee24300015fc6c67f95808d2%26intsys%3Dfe7a908b327570000b21578fac28005b#/username&state=1234567890
In addition, it is not clear to me that including two ? characters in the overall URL is supported. I'd try encoding your ?, which is the second one in the URL.
Related
I think I am misunderstanding the OAuth OpenID Connect specification and here's why:
I try to implement "Sign in with Apple". You can opt to use a popup or a redirect to an apple page I want to keep it simple at first, so I am using the redirect options. Clicking the "Sign in with Apple" button will redirect me to the apple sign in page having the state filled to prevent CSRF attacks.
After successful authentication, apple "redirects" to my specified redirect url by making a POST request to that URL with the state, code and id_token value.
Now here's the thing: How am I supposed to validate the state, when the POST request originated from a different session? I send a CSRF-Token as the state from the user who clicked on the "Sign in with Apple" button but the response from apple was made as a different session – having a different CSRF-Token.
Am I even supposed to validate the state in this kind of flow? I feel that I have to otherwise someone could just use CSRF to send a POST request to my redirect URL with an arbitrary code and id_token.
Anyone knows how to validate the state? I'd appreciate the help :D Thanks in advance.
Addition: With the popup option everything should work, I receive state, code and id_token in a browser event after successful authentication so I can validate that the state and the nonce both match.
Anyone knows how to validate the state?
It's client responsibility to validate the state to prevent against the CSRF attack. So, client must generate some state value, store it in the available storages (cookies, session, or localstorage) on its side. Pass it to the auth server. Post auth, control is redirected back from auth server to client. Now, client can retrieve the state parameter and compare it with one stored earlier. If values don't match, terminate the flow.
I've a React JS app, which makes this request to my back-end API. i.e
window.location = "https://my-server.com" + "/gmail/add_account";
cannot set HTTP headers for window.location see this
this server endpoint redirects to Google OAuth page, which returns a response to my redirect_uri.
def add_account
# no auth headers sent here, because front-end has used window.location
gmail_service = GmailService.new
session[:uid] = params["uid"]
redirect_to gmail_service.generate_authorization_url()
end
def oauth_postback
# session object is {} here
# Since there are no authorization headers, I cannot identify my app's user
# How can I identify my app's user here?
end
The problem I'm facing is that when the OAuth flow sends the response to my redirect_uri it does not return include any authorization header, due to which I'm unable to identify which user of my app has launched this OAuth flow.
I've tried setting up a session variable in the /gmail/add_account endpoint, which works fine. After this endpoint redirects to the OAuth screen, and the Oauth flow sends a response to my Oauth redirect_uri, there my session object is {}.
How can I implement this flow such that I know which user has launched this OAuth flow?
You have basically two options:
the state parameter
The state parameter is part of the OAuth2 spec (and is supported by Google). It's a random string of characters that you add to the authorization URL (as a query parameter), and will be included when the user is redirected back to your site (as a query parameter). It's used for CSRF protection, and can also be used to identify a user. Be sure that if you use it, it's a one-time value (e.g. a random value that you store in your db, not the user's ID).
sessions with cookies
If the user has previously logged in, you should be able to identify them by their session cookie. It sounds like this is the approach you're currently taking, but the session is getting reset.
It's difficult to debug this without knowing more about your stack/code, but a good first step would be just trying to load your callback URL without the redirection to Google to see the session object is still empty. If so, that would indicate an issue with how you've implemented sessions generally and not something specific to this flow.
As a note, based on the code you've shared, I'm not sure how params["uid"] is getting set if you're doing a redirect without any query parameters or path parameters.
Finally, you may consider using a managed OAuth service for something like this, like Xkit, where I work. If you have a logged in user, you can use Xkit to connect to the user's Gmail account with one line of code, and retrieve their (always refreshed) access tokens anywhere else in your stack (backend, frontend, cloud functions) with one API call.
I'm trying to implement the oAuth flow to sign in with Microsoft.
I have the following endpoints:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
https://login.microsoftonline.com/common/oauth2/v2.0/token
My flow is like this:
Redirect to Microsoft by clicking on Sign in with Microsoft button:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={client_id}&scope=user.read&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2F1%2Ffrontend%2Flogin%3Fstate%3Dtest
My redirect url is:
http://localhost:8000/1/frontend/login?state=test
Which is appended with the code I receive back from Microsoft.
I then perform a POST request to the /token endpoint.
However, I receive an error (AADSTS50011) saying:
AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application:
The data I send is correct, except for the redirect_uri. I have the following value:
http%3A%2F%2Flocalhost%3A8000%2F1%2Ffrontend%2Flogin%3Fstate%3Dtest
Which is just an url encoded version of my redirect url including the ?state=test
I know that everything works fine, except the redirect_uri, because when I remove the state query param, everything works fine.
However, to route the redirect_uri correctly in my application, I need the state param.
I cannot add it in my App settings, and I have to include it in the first request (/authorize endpoint)
That all works fine, but the second (/token) POST request fails, I cannot enter my redirect_uri with the ?state= parameter.
I've tried several options such as encoding the redirect_uri, but it doesn't help.
All other oAuth flows (Like Github) are working fine. Except Microsoft.
Attach your state param to the auth request itself, don’t put it in the redirect_uri param. Then the state param is automatically sent back to the redirect uri.
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={client_id}&scope=user.read&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2F1%2Ffrontend%2Flogin&state=xyz
I'm updating my desktop app, an Imgur client, for the upcoming deprecation of code/pin auth methods, by using a local web server to catch the redirect_url from the browser after the user authorizes access to the app. So I launch the URL in the browser, the user accepts, then Imgur redirects to
http://localhost:7710/myapp?state=auth#access_token=....&expires_in=
etc
but the browser cuts the URL at # so all the variables are missing, and my app only receives "state=auth"
from Imgur's API docs:
The response_type Parameter token: This authorization flow will
directly return the access_token and refresh_token via the redirect
URL you specified during registration, in the form of hash query
string parameters. Example:
http://example.com#access_token=ACCESS_TOKEN&token_type=Bearer&expires_in=3600
The code and pin response types have been deprecated and will soon no
longer be supported.
Imgur returns an access token to your application if the user grants
your application the permissions it requested. The access token is
returned to your application in the fragment as part of the
access_token parameter. Since a fragment (the part of the URL after
the #) is not sent to the server, client side javascript must parse
the fragment and extract the value of the access_token parameter.
Clearly they haven't thought this through for desktop applications, or am I missing something?
Imgur stuff looks non standard, since response_type=token is a basic version of the implicit flow, which used to be the solution for single page pps.
These days all UI based flows should use Authorization Code Flow (PKCE) and response_type=code.
Since your app is acting as a (loopback) web server it will not receive the hash fragment parameters, which are only available to JavaScript code running in a browser.
One option that would enable you to get the full URL would be to login via the system browser and to use a Private URI Scheme to call back to the app.
The above link is a visual blog post to explain how this works, in case it is of interest.
In my Microsoft application registration, under "redirect URLs", I've checked Allow Implicit flow and provided the URL, http://localhost:8080/event.
But I actually have an dynamic event id which makes the URL localhost:8080/event/{eventid}.
So now I'm getting an error:
The reply address http://localhost:8080/student/event/59b67936d53f013a79000009 does not match the reply addresses configured for the application
How can I give a URL that will allow any value after the event in the URL?
You cannot use a dynamic URI for OAUTH redirects. Note that this isn't specific to Microsoft's v2 Endpoint, this is the case for every OAUTH provider I've used.
I assume you're looking to redirect the user to a specific event page after they've completed the login?
The proper way to handle that is to use the state parameter. This is a string value and will be returned with the response. For example, you could encode your eventid an include that value in the state. When you get the token response back, you're app decodes the state value and redirects the user.