Why secret code is need and why not in OAuth2.0 - oauth

Why OAuth2.0 client secret is need and why not? Please explain with simple example. I am really confused after RnD.
Thanks in advance.

Authorization Code Flow
The client secret is needed during the exchange step (exchange authorization code for access token). The client sends the authorization server its client_id and client_secret so that the authorization server can verify that it really is the client.
I took this picture from https://www.youtube.com/watch?v=996OiexHze0 (22:00)
The client_secret is needed in step 3
Authorization Code Flow
Implicit Flow
During implicit flow a client secret is not used as the client does not call the authorization server a 2nd time.
This picture is also from https://www.youtube.com/watch?v=996OiexHze0 (44:37)
It shows the implicit flow
implicit flow

Related

How to use access token instead of authorization code?

I am able to generate an access token using client credential grant type
I am not sure how I can use this token in another API where an authorization code is required to get a response.
I am a newbie for OAuth 2 and completely blocked now. I am not sure do I need to generate an authorization code for my second API again or can I use token generated using client credential grant type

OAuth authorization code flow security question (authorization code intercepted by a hacker)

Something I can't wrap my head around.
As I understand the authorization code flow is supposed to be more secured than the implicit flow, because the tokens are not directly sent to the client from the authorization server, but rather retrieved by your backend.
So the flow is basically:
Browser gets the authorization code (as a URL parameter of sort).
Sends it to a public backend endpoint.
The backend sends the code + client secret to the authorization server, retrieves the tokens and stores them in the client's cookie/local storage for further use.
In this flow all the tutorials describe the authorization code as useless to the hacker, why is that? Can't a hacker use Postman or some other client and access your (public) API directly, make it go through step 3 and thus retrieve the tokens just the same?
What am I missing here?
The code is used exactly once. In many scenarios that an attacker might get access to the code, it's already been exchanged for an access token and therefore useless.
The authorization_code is a one-time token.
Authorization Code aka auth code is used publicly so that the client can establish a secure back channel between him and the authorization server so that he can exchange it with the access token without the use of a browser.
The auth code is public and can be intercepted via a proxy since it appears in the query of the redirect_uri and is used via the browser (which is considered insecure). The access token depends on the auth_code (public) and the client_secret (private) for the exchange. Without the client_secret an attacker can get the access token with brute-forcing this way through.
Summary: even if the attacker knows the authcode he can do anything without the client_secret given to the client at registration (or dynamically) and assumed to be secured.

Which one is more safe for the web app with server, PKCE Flow or standard Authorization Code Flow?

It is known that PKCE Flow is good solution for SPA or native app, rather than the standard Authorization Code Flow.
However for the web app with server ("confidential client" as defined in RFC 6749), which one is more safe?
As mentioned in this post, "PKCE is all about verifying that the client that initiated the initial authentication request is also the same that uses the authorization code to get the real tokens."
How can Authorization Code Flow with PKCE be more secure than Authorization Code Flow without client_secret
However PKCE cannot involve client credentials (client_secret), which is used in the Authorization Code Flow to make sure the requester is the authenticate client.
So seems the standard Authorization Code Flow is more safe than PKCE Flow, for the web app with server (confidential client).
Nor sure is this unstanderding correct? Because we can see in the latest oauth2.1 draft it seems prefer PKCE, as it says "PKCE is required for all OAuth clients using the authorization code flow".
https://oauth.net/2.1/
Update on May-13 2021: Actually the oauth 2.1 suggests authorization code flow plus PKCE parameters, not using PKCE instead of authorization code flow.
Amazon and Microsoft have followed the suggestion in their spec.
https://developer.amazon.com/zh/docs/login-with-amazon/authorization-code-grant.html
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
Thanks all
You can refer to this document>> https://fusionauth.io/blog/2020/04/15/whats-new-in-oauth-2-1 and references for more details.
The answer to your question is >> PKCE is safer than a normal Authorization code grant or any other grant.

Why client authentication is NOT mandatory with Authorization Code Grant and Implicit Grant in OAuth2.0

According to RFC6749 Chapter 4.1.1: https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
In the specification of Authorization Request for Authorization Code grant,
Only client_id is required for Authentication. Since client type could be public, then that means anyone can get the Authorization Code, and then use it in Access Token Request - https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3. Here you only need to supply client_id (Which is public), Authorization Code (Which can obtain with NO authentication), redirect_uri and grant_type (Not for authentication/authorization purpose), and then you will be able to obtain an access token!
My question is, why there is NO any mandatory authorization/authentication procedure for this type of grant, then what is the purpose of having this type of grant? Same thing in Implicit grant.
The client authentication is not mandatory only for the clients that are registered as public client like Mobile Native Application. The Mobile Application can not hold client secret securely, hence it is not mandatory in authorization code grant and implicit grant. The client application like web application which can hold client secret securely in the server, such clients should be registered as confidential client. The clients that are registered as confidential client should present both client id and secret for client authentication.
OAuth2 server issues an authorization code after user authentication and after user approving consent with delegating rights to the client (identified by client_id). The auth code is then sent as a parameter to a client's registered redirect URI. So I don't know what you mean by "anyone can get the Authorization Code".
Public clients should be used with PKCE OAuth2 extension. Which serves as a one-time password. So even if an auth code get stolen, it cannot be exchanged for tokens without knowing the code_verifier parameter of the token endpoint.
If an attacker creates a malicious application using someone else's client_id (pretending to be the client), the auth code will still be sent to the client's redirect URL. If the attacker gets hold of this URL handler, then it's probably a problem beyond the scope of the OAuth2 protocol.

OAuth2 authorization code PKCE without client_secret (wso2 5.3.0 IAM)

I'm currently trying to implement the OAuth 2.0 authorization code grant on a public client/native client (Android App).
Since it is impossible to store the client_secret on the device, I wanted to use this grant type with rfc7636 / Proof Key for Code Exchange by OAuth Public Clients (PKCE).
I'm using wso2 5.3.0 IAM in the backend.
The Authorization step works perfectly fine, but I'm not able to get the Access Token without a client_secret: invalid_request, Missing parameters: client_secret
Did I misunderstand the authorization code grant with PKCE wrong or did I miss some configuration in the IAM?
In comparison: It is possible with auth0.
Best Regards,
Robert
Even if you use the authorization code flow, client_secret is required at the token endpoint if the client type of your application is confidential. "4.1.3. Access Token Request" in RFC 6749 says as follows:
If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server as described in Section 3.2.1.
So, change the client type of your application to public. I don't know WSO2, but I guess that it provides settings menu to switch the client type like below.
(screenshot of Authlete's web console)
The definitions of confidential clients and public clients are described in "2.1. Client Types" in RFC 6749.
Yes, the client_secret is mandatory in WSO2 IS implementation due to the Apache OLTU library that has been used internally to implement the OAuth2 feature.
Currently there is no way to register an application as a public client as explained.
However that doesn't mean there are necessarily any security pitfalls. Basically what the recommendation says is, not to embed the client_secret in a mobile app, because it makes it vulnerable. It doesn't provide any additional security for protected backend resources, because the client request is anyway not authenticated using client_secret. If you just treat the "Base64(client_id:client_secret)" as one single string it doesn't make any difference in the protocol or security of the protocol.
So when using WSO2 IS with mobile applications, following recommendations need to be followed.
Use authorization code grant type, which requires the client_secret.
Use PKCE (after WSO2 IS 5.2.0)
If you have other type of clients or channels for the same applications, e.g. like web, then register them as a separate service provider in IS and generate a separate pair of client_id, client_secret for them.
Disable "client_credentials" grant type for the particular OAuth2 mobile client you register in WSO2 IS, so that those apps can't get an access token without user authentication.
Going one step further, if you need to have unique client credentials for each instance of the mobile applications then use OAuth2 Dynamic Client Registration (DCR) to generate client credentials on the fly.
By following above 5 recommendations, it gives you the same level of security as recommended in the specification.
For Authorization grant flow you can send the request with empty client_secret. Try putting empty string like this client_secret='' and it should work as expected. You cannot request TOKEN_URI without client_secret parameter.
PKCE is used to protect theft of authorization code, Authorization code is valid for 10 minutes, when auth code is redeemed for access_token we also send code_verifier to make sure the auth code is not stoled by someone. code_verifier and code_challenge are generated together and code_challenge is used while requesting for auth code & code_verifier is used while requesting for access_token

Resources