I am trying to use gmail smtp using oauth 2.0. I have used aspose.dll for requesting access token using authorization url. I do not get refresh token when i get the response.so there is no way to request new access token if previous is expired. So i thought of getting access token every-time my app requires . And if authorization code gets expired then i can not follow this approach.
does authorization code for gmail oauth2 ever expires??
Google's OAuth 2.0 does provide Refresh Tokens!!! This link here explains the various flows and talks about apps obtaining both access and an optional refresh token for all scenarios.
Authorization code DOES expire! That's what OAuth protocol dictates. I cannot find an exact time period to quote here for Google, but I do know that for Facebook), the authorization code expires in 10 minutes (See the december 5 change in the link.). The Refresh Token has been made available for use cases like yours. If the authorization code were to persist, what difference would remain between a Refresh token and Authorization code.
I'd suggest you look up the documentation of the Aspose libraries you are using.
PS - Authorization code/access tokens/refresh tokens are all issued by a central Google Authorization server! So, we're talking about Google's Authorization code which, as I said, does expire.
Good luck!
EDIT - Adding more info for you
The authorization code generated by the
authorization server. The authorization code MUST expire
shortly after it is issued to mitigate the risk of leaks. A
maximum authorization code lifetime of 10 minutes is
RECOMMENDED. The client MUST NOT use the authorization code
more than once. If an authorization code is used more than
once, the authorization server MUST deny the request and SHOULD
revoke (when possible) all tokens previously issued based on
that authorization code. The authorization code is bound to
the client identifier and redirection URI.
Source - https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-31
Section - 4.1.2
Related
In the article at MSDN, it says that the following request needs to be performed to get a new access token using a refresh token for a web app.
POST /.../v2.0/token
Content-Type: application/x-www-form-urlencoded
?client_id=...
&scope=wide_and_proud
&refresh_token=OAAABAAAAiL9Kn2Z27UubvWFP...
&grant_type=refresh_token
&client_secret=hakuna_matata
It means that we'd need to distribute the client's secret to the frontend application, which, to me, opens a huge security gap. I want to argue that we should never-ever feed our SPA with the information on client's secret.
I've been googling it for a few days and all the resources somehow point to a case where we do provide client's secret. However, I can't shake of the sensation that it's not what's supposed to be applied in the case of an SPA authenticating using authorization code flow. However, I see no documentation specifically discussing the combo: "spa refresh token authorization code flow".
You are right that the SPA should not use a client secret. It should also avoid use of refresh tokens. The problem is that the SPA has nowhere secure to store this information.
PKCE
An SPA is a public client and can use a one time use runtime secret rather than the client secret field. See this Proof Key for Code Exchange summary for details. This would solve the initial problem.
The Token Handler Pattern
If you want to go further, there is a wider issue is that an SPA needs a server component (API) that will look after its secrets and tokens. The SPA can then make a request such as this and the API can deal with sensitive data:
POST /login/end { url: location.href }
If this is done in an API driven manner it also fits very nicely with the goals of an SPA architecture, though it does add more moving parts. See these resources for further info:
React Code Example
Simplified SPA OAuth Code
Docs
Note also that this is a general design pattern. It will work with Microsoft and any other Authorization Server.
Token Handler First Steps
You could start with just these steps, which would also keep refresh tokens out of the SPA:
SPA calls API at /login/start to get the redirect URI
API sets a temp cookie with state + PKCE parameters
SPA redirects and receives the response
SPA calls API again, at /login/end
API then supplies the client secret to the Authorization Server
API stores refresh tokens in a secure cookie
API returns short lived access tokens to the SPA
I was creating an application to enable user to sign in with their Microsoft Account. But after the submission of email and password, it displays this error message "AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token". What is the problem? Here is the link to my GitHub project: https://github.com/JadyVella/OAuth2-with-MSAL
Based on the AADSTS54005: OAuth2 Authorization code was already redeemed Error code.
If your app reuses authorization codes to get tokens for multiple resources, its recommended that you use the code to get a refresh token, and then use that refresh token to acquire additional tokens for other resources. Authorization codes can only be used once, but refresh tokens can be used multiple times across multiple resources. Any new app that attempts to reuse an authentication code during the OAuth code flow will get an invalid_grant error.
For more information about refresh tokens, see Refreshing the access tokens . If using ADAL or MSAL, this is handled for you by the library - replace the second instance of 'AcquireTokenByAuthorizationCodeAsync' with 'AcquireTokenSilentAsync'.
Note : If the issue is not resolved from above, Please reach out to Azure Support by clicking on (Help+Support) and creating a technical request to Azure as it may require assisted support.
I'm learning OAuth 2.0. When using authorization code flow, it's enough to pass client ID. Does it mean that, in theory, an attacker can generate multiple authorization codes easily?
What was the reason why the consent screen doesn't use client secret? It's secure, as authorization server should deliver HTTPS connection.
Is it only for simplicity, to allow linking on client-side, like this?
Login with Koala Auth
No, according to RFC-6749 section 1.3.1, the user is authenticated by the Authorization Server before an authorization code is given back. Therefore, the client ID is not the only piece of data the is needed to get an authorization code.
This is not because the resource owner redirects the user-agent to the authorization server that this authorization server will give back an authorization code: the user-agent must complete an authentication step with a valid user, before the authorization code is given back to the resource owner.
In order to access resources in Azure AD web applications we retrieve an authorization code using the following workflow:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v1-protocols-oauth-code
Now my questions is, does this retrieved code also have a specific lifetime (like tokens have) or will it never expire? I guess it won't expire but I need to be sure about that.
Yes, the authorization code has a lifetime of 10 minutes I think.
You use it to get the tokens you need and then throw it away.
You'll get refresh tokens so you can use them to get more tokens later.
ADAL.NET for example handles the token refresh for you, assuming you properly implement a token cache.
Reference: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-id-and-access-tokens (scroll all the way down) (it's for the v2.0 endpoint, but codes are similarly short-lived in v1)
Authorization codes (work or school accounts)
10 minutes
Authorization codes are purposely short-lived, and should be immediately redeemed for access tokens and refresh tokens when the tokens are received.
I tried to login with two separate website, both using "login with Google". Intercepted the auth code from the 1st site, and exchange it with the auto code to the 2nd site. Neither site will let me login. I remember in RFC6749 it is not specified that the auth code to be bound with any identity, is it implemented so to increase security?
This is indeed part of OAuth2.0 security:
Exchange the Authorization Code for an Access Token
We’re about ready to wrap up the flow. Now that the application has
the authorization code, it can use that to get an access token.
The application makes a POST request to the service’s token endpoint
with the following parameters:
grant_type=authorization_code - This tells the token endpoint that the
application is using the Authorization Code grant type.
code - The
application includes the authorization code it was given in the
redirect.
redirect_uri - The same redirect URI that was used when
requesting the code. Some APIs don’t require this parameter, so you’ll
need to double check the documentation of the particular API you’re
accessing.
client_id - The application’s client ID.
client_secret -
The application’s client secret. This ensures that the request to get
the access token is made only from the application, and not from a
potential attacker that may have intercepted the authorization code.
from https://developer.okta.com/blog/2018/04/10/oauth-authorization-code-grant-type#exchange-the-authorization-code-for-an-access-token
Short answer : Authorization code is bound to the client it was issued
This is strictly enforced by the RFC6749 and stated in 4.1.3. Access Token Request section. Also, it is one of many checkes authorization server perform to validate a token request. Specification has following stated,
The authorization server MUST:
o ensure that the authorization code was issued to the authenticated
confidential client, or if the client is public, ensure that the code
was issued to "client_id" in the request
So when authorization server will cross check authorization code against client id or client credentials depending on client type.
Furthermore, authorization code is a temporary secret which must not be exposed to other parties. This is highlighted in security consideration's 10.5. Authorization Codes section.