What is the purpose of authorization code in OAuth
Asked Answered
C

3

20

In oauth you make a request using you client id/secret to get an authorization code. Then you make a second request to exchange the authorization code for access token. My question is:

Why is this two step process required instead of getting access token in the first place? How does it make the whole process more secure? Or is there another reason.

I'm talking about server side app (like php for example) requesting authorization from a remote server, not javascript.

Chiseler answered 1/1, 2019 at 12:30 Comment(0)
S
9

It's possible to do it with a single request - it's called the implicit flow then. There is a single request with response_type set to token or id_token token.

The general idea of using access code (authorization flow) instead of directly returning the tokens is to hide them from the end user. The second request is done usually by the backend server instead of a browser.

You can find more details here: https://auth0.com/docs/api-auth/which-oauth-flow-to-use

Note: for complete answer read the comments.

Sideburns answered 1/1, 2019 at 12:34 Comment(7)
But the access code is not hidden from the user (or software on the user machine). What if a bad software like browser plugin, exchanges the access code for a token first. Wouldn't it be safer the authorization server to use redirect_url just as a landing page, but post the code via direct post request to the client app without passing through the user browser at all.Chiseler
The access code is not - however to exchange the access code to tokens you need to provide client_id and client_secret which are unknown for the user.Sideburns
Then the access code is not needed at all. You can just request access token after the server have granted access to your client id/secret. The server knows that you have access. Why does it need access code to prove it?Chiseler
Client id and secret are for the application - not for the user. Access code is granted based on the user credentials. So I (Jakub) login to LinkedIn and get the access code. Then your application using my access code and your client id/secret retrieves my access token from LinkedInSideburns
The implicit grant type is not recommended anymore. You should always use the authorization code grant type with PKCE for public clientsLibertine
"The second request is done usually by the backend server instead of a browser." Then Backend Server anway have to respond the Client with access token right ? How does this step ensures further safety. I am confused still.Steeplebush
"The second request is done usually by the backend server instead of a browser." So this way the web app backend server can have a secret that does not make it to the browser? I don't quite see how an added step with the "authorization code" affects that. Can someone provide an example attack that would be prevented in this flow, but would not in the implicit "one step" flow?Site
F
4

In oauth you make a request using you client id/secret to get an authorization code.

Authorization code request does not contain the client secret. It only contain the client ID and redirect url, which enable authorization server to validate the request to originate from a known client.

What is this two step process required instead of getting access token in the first place? How does it make the whole process more secure? Or is there another reason.

If we forget about implicit flow, which involves retrieving access token from first call, I would say it is to improve security.

When authorization code flow is used, you use a user agent (browser) to initiate the flow. This means, the user agent will redirect end user to authorization server for authentication (username password obtaining and validating end user). If end user validation succeed, authorization server sends the authorization code. This is a temporary secret, which is bound to original authorization code request.

Now client use the authorization code and directly contact authorization server to obtain access (and other) tokens. This second step occur outside the user agent.

If the client is a confidential client, a client which has a client ID as well as a client secret, this second call will require to produce this client secret. So it internally contain a client validation process. From authorization server perspective, token request will be rejected if client authentication failed. This gives protection for authorization code stealing.

Also, with the second step, we avoid access token exposure to third party. For example, in implicit flow, access token is sent as URL fragments through user agent. If user agent is compromised (ex:- Manipulated by some malicious code) this access token can be extracted.

What about public clients ? That means clients which does not get a client secret due to their nature (ex:- Clients which cannot protect the secret by storing)

Public clients use PKCE. It is a must to use this to avoid authorization code stealing. So in the token request (second call), client will directly send code verifier. User agent cannot obtain code verifier in the first request since it was hashed (code challenge). So token request now contains a secret that only known by client and authorization server.

If you compare both scenarios (public and confidential clients), you can see how the second call adds an extra layer of security.

Fayola answered 2/1, 2019 at 2:58 Comment(2)
I don't understand what exactly makes it more secure. What kind of an attack would PKCE prevent? Would it stop a malicous browser plugin somehow?Site
@Site I think PKCE RFC introduction explains a lot about what short of attack it tries to prevent [1]. In short, PKCE protects public clients from authorization code stealing, where the client shares a common platform with other applications (ex- mobile app). [1] - rfc-editor.org/rfc/rfc7636#section-1Fayola
M
0

More secure... Or less? Depends on how it's applied.

Have a look at: https://auth0.com/docs/api-auth/which-oauth-flow-to-use

You'll notice that the auth code flow is used when it's used on the server side. Also do notice that when an auth code is requested the response url has a query string with a question mark: https://example-app.com/redirect?code=g0ZGZmNjVmOWI&state=dkZmYxMzE2

When using a spa, you'll be using the implic flow. Notice that the accesstoken is sent through an anchor(#) in the url https://example-app.com/redirect#access_token=MyMzFjNTk2NTk4ZTYyZGI3

An anchor value will never be sent to the server. It will only be available to the client in the spa. The server will never be able to see the access token.

When a server app gets a redirect it must be able to read it. It can, because the url has a question mark instead of a #. If it would send the token directly, the client could see the access token in his browser history, or through fiddler.

Mold answered 4/1, 2019 at 14:36 Comment(1)
This does not explain the "authorization code". Perhaps it is important whether a value is sent via a query parameter or via a url fragment, but that is not what the question is really about. Why is it used in the first place?Site

© 2022 - 2024 — McMap. All rights reserved.