The implicit grant is a simplified authorization code flow optimized
for clients implemented in a browser using a scripting language such
as JavaScript.
The resource owner password credentials (i.e., username and password)
can be used directly as an authorization grant to obtain an access
token.
(https://www.rfc-editor.org/rfc/rfc6749#section-1.2)
My question is about understanding how these two grant types are different?
Important to understand here is the way and place you enter your credentials.
Implicit
Your app is https://example.com and for authentication, you are going to https://auth.some-domain.com (or even https://auth.example.com). After successful authentication, user is redirected to https://example.com/some-callbackurl?#token=token-value.
Points to be noted: Redirection and token in URL
Resource Owner Password flow
Your app is https://example.com and for authentication, you are going to https://example.com (or https://example.com/login). After successful authentication, user is redirected to https://example.com/home.
Points to be noted: No redirection and no token exchange in URL
Basically if you are owning the app (client app, server app, auth app) then this is something you would do. Basically you are the one who is in charge of authentication - not a third party app. You trust your client app.
https://example.com/login gets credentials from user and does a HTTP REST POST (for example) call and get a response as token (and refresh token - optionally). It saves it in localStorage or cookie and then redirects to home page or whatever page it has to redirect to.
No redirection happens in exchange.
As you quoted, the "Resource Owner Password Credentials Grant" is suitable in cases where the resource owner has a trust relationship with the client, such as the device operating system. An example is Facebook application - Facebook trusts their app that is installed on the device.
Thus, client-app does not have to be registered in the auth-server. As you can see in the request the client_id is not transferred as a param. In addition, the flow is simpler - the access token is retrieved within a single request.
Related
I am developing mobile application that works with server side using OAuth2. For authorization we use OpenID Connect with authorization code flow. Typical step in the authorization process on mobile devices in this flow is to open authorization url in system browser and then capture redirect url with authorization code.
In case when user is required to enter login and password in browser it is OK. But we have some clients authorized by IP and in this case system browser auto closes immediately after launch and returns successful authorization. Such useless browser launch is annoying and I'd like to prevent it.
The only idea I have right now is to make direct HTTP authorize request with prompt=none parameter as described in https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest to try authorize by IP. And in case of login_required or interaction_required errors repeat it in system browser without prompt parameter.
prompt=none
The Authorization Server MUST NOT display any authentication or
consent user interface pages. An error is returned if an End-User is
not already authenticated or the Client does not have pre-configured
consent for the requested Claims or does not fulfill other conditions
for processing the request. The error code will typically be
login_required, interaction_required, or another code defined in
Section 3.1.2.6. This can be used as a method to check for existing
authentication and/or consent
Is there any other way to detect moment in authorization flow when user interaction with web page is really needed? So I can open browser only if it is needed. And without additional requests useless for most clients.
Since you use OpenID Connect, you might think of enabling some other mechanism to maintain authorized state between application, backend and identity server.
One such scenario could be usage of Access and Refresh tokens,
First login, end user authentication is mandatory
Your app receive tokens (ID token, access token and refresh token)
Customer use the app and app use access token to communicate with the backend
Customer use the application second time
You know previous access token is expired so you obtain a new access token using refresh token
Of course refresh token can expire or identity serve can revoke the access token for some reason (ex- user changing password). But IMO this is the best solution provided by specification itself.
So, I'm developing an API using slim/slim and league/oauth2-server to manage the OAuth2 connection. OAuth2 will be useful because I will need to use Client Credentials grant between services.
Then, I'm also developing an hybrid app with React Native. This app will requires user login by using e-mail and password or connecting with another services (such as Facebook, Google, Twitter, etc).
And I'm confused about what OAuth2 flow to use for this case. Across the web are a lot of articles saying that Resource Owner Password Credentials is not safe anymore, and we should use instead Authentication Code with PKCE.
But I can't discover or understand how to apply Authentication Code with PKCE in a first party app, because all documentation talks about you will need the uses a browser to get authentication code in redirect_uri.
The flow I imagine is something like that:
User open the app, then insert your credentials username and password;
This screen will connect to API /request_token URI sending { 'grant_type': 'password', 'username': username, 'password': password, 'client_id': CLIENT_ID }, considering it as a public app we can't send client_secret;
The API validates credentials and returns some data such as { "access_token": access_token, "token_type": "JWT", "expires_in": LIFE_SPAN }, here we will use JWT to gerenate the access_token based in public/private key;
Authentication done, the app will store the access_token while it's alive and when it expires will do the flow to refresh_token.
My question: is it safe? Scott Brady did some "aggressive" article talking it's NEVER safe.
How apps does this things? When I use Instagram app, for example, they own the app and the API, I don't need a browser in the User Experience flow. Are modern apps using "Resource Owner Password Credentials" or "Authentication Code with PKCE"? There is a away to avoid insert browser in the flow while using "Authentication Code with PKCE"?
[EDIT] Possible Solution
As Gary Archer said "Auth Code flow with PKCE is recommended - along with logging on via the system browser", but we are not talking about grant permissions to access users data or third-party apps.
As a designer I don't agree that loggin in the first-party app owned by the same API owner requires a browser this is the not the User Experience we are looking for. And all apps we see such as Instagram, Facebook, Uber... we just put your username and password and we have access to your account.
What I will do is create a custom version of Authentication Code with PKCE removing the required_uri.
[EDIT:2] The New Flow
After a lot of search, I found some answers I think was interesting to adapt. As above, I removed redirect_url from flow. Look:
The flow starts in a login screen, when user give your credentials;
Client generates a code_verifier then hashes code_verifier to code_challenge and sends it to Authorization Server with following parameters:
response_type=code : indicates that your server expects to receive an authorization code.
client_id=xxxx : the client id.
client_integrity=xxxx : app integrity check for first-party app.
code_challenge=xxxx : the code challenge generated as previously described.
code_challenge_method=S256 : either plain or S256, depending on whether the challenge is the plain verifier string or the SHA256 hash of the string. If this parameter is omitted, the server will assume plain.
username=xxxx : username to authenticate.
password=xxxx : hashed version of password.
state=xxxx : a random string generated by your application (CSRF protection).
Authorization Server will validates user authentication, stores code_challenge and return the authorization_code with a client_token;
After receive the aauthorization_code and client_token, Client saves the client_token and immediately send authorization_code back to Authorization Server with following parameters:
grant_type=authorization_code : ndicates the grant type of this token request.
code=xxxx : the client will send the authorization code it obtained.
client_id=xxxx : the client id.
code_verifier=xxxx : the code verifier for the PKCE request, that the client originally generated before the authorization request.
Authorization Server will validates all data and, if everything is right, will return the access_token;
Client will set Authorization header with the access_token and always send client_token to every request, it will be only accepted with both values are right;
If access_token expires, then Client will do a request to refresh access_token and get a new one.
Now, I will reproduce this logic to PHP language. If everything goes right and I hope it does, I will be back with definitive answer.
[EDIT] Clarifications
I'm using OAuth2 to user connect with your third-party accounts (Google, Facebook, etc). But user also can log to a local account in my database. For this case, user doesn't need to grant anything at all. So, no makes sense send user to a browser to him does your login.
I wondering if, to this case, local accounts, we can use Resource Owner Password Credentials or it's more safe Authentication Code with PKCE (we already conclude it's a better approuch). But Authentication Code with PKCE requires redirect_uri, do I need uses this redirection to log users into a local account where they don't need to grant access?
Let's go then. After a lot research, I found some approaches that I will apply and may work correctly. So, first of all, here is the challenges:
You must never trust in clients running in client side. There's a lot of concerns about, your applications can be decomplied, modified, the users devices can be with a malware or connection may suffer with a man in the middle attacking (MITM)...
An API Server, even using OAuth2, will be able to only identify WHO is accessing the resources, but not WHAT is accessing. Therefore, any sensitive information will be dangerous, anything can steal it and uses it.
Resource Owner Password Credentials makes part of OAuth2 protocol for authorize resource owner to access your resources. So, it doesn't make part of authentication process and you will your ruin if you treat it like that;
By using ROPC grant type there is no way to know if resource owner is really making that request, what make "easy" a phishing attack. Reminds about "you know WHO and not WHAT". For last, this kind of grant makes easy for whatever thing assumes the user identity;
This grant type also goes against OAuth2 propourse, since OAuth seeks to avoid the password use to access resources. That why many people say to don't use it;
For reinforce, it's important to highlight ROPC is not authenticating user, but it just authorizing him to access the resource server.
And yes, ROPC allows for refresh tokens, but there are two issues: first, client needs resupply credentials each time needed to get a new token; second, if using a long-term access code, then things get more dangerous.
To prevent a malicious thing from arbitrarily using user credentials there are access tokens. They replace passwords and needed to be refreshed in short amount of time. That's why they are so much better than HTTP Basic Authentication.
That's why is recommended to use in modern apps the Authentication Code with PKCE, it provides all features and benefits of using OAuth2 protocol. But, here cames a long discussion and, even, problem for developer community:
To get an Authentication Code some user needs to make your login in a browser, grant access, redirect back to client and, soon, client will receive a code to exchange for an access token.
This scenario works good and NEEDS to be used for third-party apps. But, what if it is a first-party app? When you own the database with user data and you own the "trusted" app, redirect user doesn't make any sense. Right?
At this moment, my question is: how can I use the AuthCode (PKCE) flow without redirect user? And, again, it's important to highlight that talking about OAuth2 protocol is always the same that "to grant client to access resource server" (authorization, not authentication).
So the real question is: why Authorization Code needs a redirection at all? Then, I came with the following answer:
This flow requires to know client credentials and user consensus to turn back an authorization code.
That's why I was wrong in my edits. There's no change needed in OAuth2 protocol (sorry me for think different). For this reason, what OAuth2 needs is a authorization mediator, above your layer. Thus, the authorization code not will turn back to client, but to authorization mediator that, finally, will return it to client. Makes sense?
How it gonna work? Well, will be need 4 different "cores":
Authentication Server: will be responsible to authenticate user credentials and client identity. The main objective is to prove "WHO is the user and WHAT is connecting to get authentication";
Authorization Mediator (one layer above OAuth2): will validate client unique identity to ensure client/user is "know" and can get an access token;
Authorization Server: makes part of OAuth2 implementation, nothing change. Will authorize a client to get your authorization code, access tokens an refresh tokens;
Resource Server: will allow access resources through an access token.
And, then, security techniques we may consider:
API Key: each application (client) will have your own API Key with permissions scopes associated with those keys. By using it, you can gather basic statistics about API usage. Most API services use statistics to enforce rate limits per application to provide different tiers of service or reject suspiciously high frequency calling patterns;
Mutual SSL Authentication: by using this technique client and server exchange and verify each other's public keys. Once the keys are verified, the client and server negotiate a shared secret, a message authentication code (MAC) and encryption algorithms;
HMAC: API Key will be separeted into an ID and a shared secret. Then, as before, the ID is passed with each HTTP request, but the shared secret is used to sign, validates and/or encrypt the information in transit. The client and server will exchange the shared secret with algorithm such as HMAC SHA-256;
Protecting code application: using code obfuscators will make harder to locate and extract sensitive data from app, such as secret shared, api keys, public keys...
Handle user credentials: providing a simple method to user login and prove your identity. After insert valid credentials, server can return a user token (JWT) and emulates a user session with this.
Let's look at flow:
Part one: autheticating user and client;
User will type your credentials and be asked to prove your identity using your e-mail or mobile number, after Client will send user credentials (such as { email, mobile_number, hash ( password ), verification_method }) to Authentication Server route /login;
Authentication Server will validate user credentials and send a one-time password to user confirm your identity (for e-mail or mobile number as choose by user);
Then, user will insert the OTP received and client will send back to Authentication Server route /login-otp including the verification method (such as { otp, verification_method });
At the end, Authentication Server will return a { hash ( shared_secret ) } to be used soon.
Part two: authorizing API access;
When receive shared_secret Client will stores securely at mobile app, then it will ask for a authorization code using PKCE calling /auth with { response_type, client_id, scope, state, code_challenge, code_challenge_method }, Authorization Server will validate credentials and return an authorization code with no redirects;
Later, Client will exchange received code to an access token accessing /token, but it will need to send some extra data: { payload: { grant_type, code, client_id, code_verifier }, timestamp, hash ( some_user_data + timestamp + shared_secret ) };
Authorization Mediator will receive this request and validate trying to generate the same hash generated by user. And redirect all data to Authorization Server that will validate client_id, code and code_verifier responding with an access token;
This new access_token will return to Authorization Mediator and, after, to client granting access to API resources.
Part three: accessing resource server;
Client will each time needs send a call to API /api containing the Authorization header and some extradata with { timestamp, hash ( some_user_data + timestamp + shared_secret ) };
Authorization Mediator will validates the shared_secret hashes, call Resource Server validating access_token and return data.
Part four: refreshing access token;
After access token expires, Client will send a call to /refresh-token containing the Authorization header and some extradata with { payload: { grant_type, refresh_token, client_id, scope }, timestamp, hash ( some_user_data + timestamp + shared_secret ) };
Authorization Mediator will validates the shared_secret hashes, call Authorization Server and return a new fresh token access.
A visual image for this flow:
I don't think it is a perfect strategy, but it replaces Resource Owner Password Credentials to Authentication Code with PKCE and gives some extra security techniques. It's way better then a single and simple authentication method, preserves the OAuth2 protocol and mantaein a lit bit more hard to compromise user data.
Some references and support:
How do popular apps authenticate user requests from their mobile app to their server?
Why does your mobile app need an API key?
Mobile API Security Techniques
Secure Yet Simple Authentication System for Mobile Applications: Shared Secret Based Hash Authentication
Auth Code flow with PKCE is recommended - along with logging on via the system browser. Also the AppAuth pattern is recommended.
https://curity.io/resources/develop/sso/sso-for-mobile-apps-with-openid-connect/
It is tricky and time consuming to implement though - so you need to think about it - sometimes using a cheaper option is good enough. Depends on the sensitivity of data being exposed.
If it helps here are some notes for an Android demo app of mine, which also focuses on usability - and links to a code sample you can run:
https://authguidance.com/2019/09/13/android-code-sample-overview/
First of all, do not invent a OAuth grant simply because you need to adopt it in your application. It will make tings complex to maintain.
In your scenario you need to provide social login (ex:- Login via Google, facebook). This of course a desired functionality one must support. But it doesn't limit you from obtaining end user credentials through a custom registration process. There are many reasons for this, for example not everyone use social media or a Google account. And sometims people prefer to register than sharing user identifier of some other service (yes, this is the opposite end of social login).
So go ahead, provide social login. Store user identifiers when first login through external identity server (ex:- Google). But also, have a good old registration step with password and an email.
I am quite new to Asp.net core identity and Identity Server 4. I am following online training course on implementing Authentication using Open Id Connect with asp.net core and Identity server 4.
If I further illustrate my solutions having Asp.net core mvc web application as client. Another asp.net core mvc web app as IDP (Identity Server4) and another asp.net core mvc web api as resource server.
For un-authenticated Users Login page on IDP is appearing. Problem for me is how does client web (asp.net core web app) knows user is not authenticated? My guess is when user first time access web app access token is not presenting on authorization header so authentication middleware knows this is not authentication request and redirect request to IDP Is it correct?
Then user redirect to Logic view of Account Controller how that redirection configured on IDP (I mean here is how exactly redirect to Account controller login page)?
Furthermore what is purpose of RedirectUris(https://localhost:44326/signin-oidc) configure on IDP. and how it works
By the way in here I am using Authorization Code flow and IdentityServer4.Quickstart.UI AccountController comes from there.
Either you know what api needs authentication, therefore, if you don't have this token available anywhere, you shall redirect the user to the oauth server. Once this one redirects back on your application, you will find the token in the url (a parameter of it if my memory is good). This token will have to be saved in memory for later usage or in your application db (standard browser feature). Then you can make a call to the api using this token that you stored.
If you don't know what api needs authentication or if your token is expired, you make the call to the api anyway, and then you get an 403 error (not authorized). Any 403 error should make the client application decide to redirect the user on the authentication portal to get an new token.
As you use code flow, I suppose you must develop a react, angular or any spa application. So I advice you to use oidc-client. It is a javascript library that is developed by the same guys who developed identity server. It makes the client very simple to develop when dealing with oauth authentication.
Here a more detailed description of the process and check/variable that are done/used:
The client application (javascript/html5) makes a call to the resource server without any token in the authentication http request header
The resource server (your api server) tries to get the token in the header
doesn't exists. This means the request is not authenticated.
The resource server return an 403 error to the client before even making any controller call or even authorization checks (roles and such)
The client catches this 403 error, and then knows that a token is necessary for this call.
The client stores the url of the request that failed and its post (if applicable) in the application db
The client redirects the browser to the authentication server url, by transmitting the client id (the identifier of the javascript/html5 application for the authentication server), the scope (what set of resource that should be used by this client application in the context of this authentication request) and the url where the authentication server should reidrect the user back once he is authenticated.
The authentication server asks the users to authenticate (in any way you can imagine, but most of time it is by asking him a login and a password)
if the user is recognized by the authentication server (password that matches the login), this one will check if the return url (the url that was transmitted by the client application for it to be used to redirect the user on the right page once he is authenticated) is in the list of granted return urls for this client application (the RedirectUris you are wondering about). The point of this is to ensure that the the issued token is not transmited to an ungranted application (like a external javascript/html5 application hosted in china that could find a way to suck some data from your api server that only your user can know about and submitting it to a russian api server without the user even noticing it)
it also checks if this client application (not the user... here it's to ensure that a specific client javascript/html5 application can access a set of resources) can use the scope that is requested.
if checks are ok, the authentication server issues an access_token by signing it with its private key.
the authentication server redirects the user on the initially transmitted return url, by setting the access_token in the url as a parameter.
the client application get this parameter and stores it somewhere (anywhere you want, but most of time in the application db and in memory)
the client application get the url that stored for the call to be done again, but with the access_token in the authentication header this time
the api server (or resource server) receives the http request again
finally find an access_token and checks if the it was actually issued by the authentication server (using its public key) since it is the only tiers that is trusted to issue a token.
then it can trusts what is in the token: the user id that is mentionned inside, scopes (set of features) that are allowed to be accessed, etc...
then it calls the controller and returns the response. If the token is expired, (a simple date that is in the token) it doesn't make any call to the controller and return a 403.
FYI, anything that is in the token can be trusted if its signature has been done by then authentication server. This system prevents the man in the middle security breach. Meaning: a guy who got a token by spying the network activity, changes what is inside this token so that he can make any call he want against your api server. Any changes that is made in this token will be detected because the signature (some sort of encrypted hash) won't match the new content anymore. And this signature, if everybody can check it in the world with the public key, only one tiers can issue it with its private key: the authentication server.
I tried to make it as complete as possible and yet still understandable for a newbie in oauth that you claim to be. Hope this helps.
I'm building a web app that uses the Oauth2.0 protocol. I have registered my app with the authorization server and received my client id and client secret.
I'm now working on Authorization part and specifically using the Authorization Code grant type. In that process i'm sending the user to the authorize endpoint with the following query parameters:code, client_id, redirect_uri, scope and state. (omitting the client_secret)
The problem that i'm dealing with is i'm getting an error back saying I need to provide the client_secret as well.
I was under the impression the client_secret is not needed at this part and shouldn't be sent in this request but rather when the client sends the authorization code (along with id & secret) to obtain the access token.
So my question is, Is it wrong (against oauth 2 protocol) that the authorization server requires the client secret to be sent in the request for the authorization code?
I am not 100% sure of this, but I did some research myself and what I found is that is not a real problem not to keep the "client secret" a secret. The only possibility of someone malicious being able to get through the Authorization specs is prevented by some facts:
1. Client need to get authorization code directly from the user, not from the service
Even if user indicates the service that he/she trusts the client, the
client cannot get authorization code from the service just by showing
client id and client secret. Instead, the client has to get the
authorization code directly from the user. (This is usually done by
URL redirection, which I will talk about later.) So, for the malicious
client, it is not enough to know client id/secret trusted by the user.
It has to somehow involve or spoof user to give it the authorization
code, which should be harder than just knowing client id/secret.
2. Redirect URL is registered with client id/secret
Let’s assume that the malicious client somehow managed to involve the
user and make her/him click "Authorize this app" button on the service
page. This will trigger the URL redirect response from the service to
user’s browser with the authorization code with it. Then the
authorization code will be sent from user’s browser to the redirect
URL, and the client is supposed to be listening at the redirect URL to
receive the authorization code. (The redirect URL can be localhost
too, and I figured that this is a typical way that a “public client”
receives authorization code.) Since this redirect URL is registered at
the service with the client id/secret, the malicious client does not
have a way to control where the authorization code is given to. This
means the malicious client with your client id/secret has another
obstacle to obtain the user’s authorization code.
// copy paste of hideaki answer
Concluding
OAuth2 specify that you need to inform your secret into a request if your application is a server-side based app (different than a single-page application or mobile) which does not make its source code available. However, if you can't control your base code, like in an native mobile application, you should look for another solution.
References
OAuth2 Documentation
Bear similar stack question
Simplifying OAuth2
OAuth 2.0 has multiple workflows. I have a few questions regarding the two.
Authorization code flow - User logs in from client app, authorization server returns an authorization code to the app. The app then exchanges the authorization code for access token.
Implicit grant flow - User logs in from client app, authorization server issues an access token to the client app directly.
What is the difference between the two approaches in terms of security? Which one is more secure and why?
I don't see a reason why an extra step (exchange authorization code for token) is added in one work flow when the server can directly issue an Access token.
Different websites say that Authorization code flow is used when client app can keep the credentials secure. Why?
The access_token is what you need to call a protected resource (an API). In the Authorization Code flow there are 2 steps to get it:
User must authenticate and returns a code to the API consumer (called the "Client").
The "client" of the API (usually your web server) exchanges the code obtained in #1 for an access_token, authenticating itself with a client_id and client_secret
It then can call the API with the access_token.
So, there's a double check: the user that owns the resources surfaced through an API and the client using the API (e.g. a web app). Both are validated for access to be granted. Notice the "authorization" nature of OAuth here: user grants access to his resource (through the code returned after authentication) to an app, the app get's an access_token, and calls on the user's behalf.
In the implicit flow, step 2 is omitted. So after user authentication, an access_token is returned directly, that you can use to access the resource. The API doesn't know who is calling that API. Anyone with the access_token can, whereas in the previous example only the web app would (it's internals not normally accessible to anyone).
The implicit flow is usually used in scenarios where storing client id and client secret is not recommended (a device for example, although many do it anyway). That's what the the disclaimer means. People have access to the client code and therefore could get the credentials and pretend to become resource clients. In the implicit flow all data is volatile and there's nothing stored in the app.
I'll add something here which I don't think is made clear in the above answers:
The Authorization-Code-Flow allows for the final access-token to never reach and never be stored on the machine with the browser/app. The temporary authorization-code is given to the machine with the browser/app, which is then sent to a server. The server can then exchange it with a full access token and have access to APIs etc. The user with the browser gets access to the API only through the server with the token.
Implicit flow can only involve two parties, and the final access token is stored on the client with the browser/app. If this browser/app is compromised so is their auth-token which could be dangerous.
tl;dr don't use implicit flow if you don't trust the users machine to hold tokens but you do trust your own servers.
The difference between both is that:
In Implicit flow,the token is returned directly via redirect URL with "#" sign and this used mostly in javascript clients or mobile applications that do not have server side at its own, and the client does not need to provide its secret in some implementations.
In Authorization code flow, code is returned with "?" to be readable by server side then server side is have to provide client secret this time to token url to get token as json object from authorization server. It is used in case you have application server that can handle this and store user token with his/her profile on his own system, and mostly used for common mobile applications.
so it is depends on the nature of your client application, which one more secure "Authorization code" as it is request the secret on client and the token can be sent between authorization server and client application on very secured connection, and the authorization provider can restrict some clients to use only "Authorization code" and disallow Implicit
Which one is more secure and why?
Both of them are secure, it depends in the environment you are using it.
I don't see a reason why an extra step (exchange authorization code
for token) is added in one work flow when the server can directly
issue an Access token.
It is simple. Your client is not secure. Let's see it in details.
Consider you are developing an application against Instagram API, so you register your APP with Instagram and define which API's you need. Instagram will provide you with client_id and client_secrect
On you web site you set up a link which says. "Come and Use My Application". Clicking on this your web application should make two calls to Instagram API.
First send a request to Instagram Authentication Server with below parameters.
1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token.
You don't send client_secret, You could not trust the client (The user and or his browser which try to use you application). The client can see the url or java script and find your client_secrect easily. This is why you need another step.
You receive a code and state. The code here is temporary and is not saved any where.
Then you make a second call to Instagram API (from your server)
1. `grant_type` with the value of `authorization_code`
2. `client_id` with the client identifier
3. `client_secret` with the client secret
4. `redirect_uri` with the same redirect URI the user was redirect back to
5. `code` which we have already received.
As the call is made from our server we can safely use client_secret ( which shows who we are), with code which shows the user have granted out client_id to use the resource.
In response we will have access_token
The implicit grant is similar to the authorization code grant with two distinct differences.
It is intended to be used for user-agent-based clients (e.g. single page web apps) that can’t keep a client secret because all of the application code and storage is easily accessible.
Secondly instead of the authorization server returning an authorization code which is exchanged for an access token, the authorization server returns an access token.
Please find details here
http://oauth2.thephpleague.com/authorization-server/which-grant/
Let me summarize the points that I learned from above answers and add some of my own understandings.
Authorization Code Flow!!!
If you have a web application server that act as OAuth client
If you want to have long lived access
If you want to have offline access to data
when you are accountable for api calls that your app makes
If you do not want to leak your OAuth token
If you don't want you application to run through authorization flow every time it needs access to data. NOTE: The Implicit Grant flow does not entertain refresh token so if authorization server expires access tokens regularly, your application will need to run through the authorization flow whenever it needs access.
Implicit Grant Flow!!!
When you don't have Web Application Server to act as OAuth Client
If you don't need long lived access i.e only temporary access to data is required.
If you trust the browser where your app runs and there is limited concern that the access token will leak to untrusted users.
Implicit grant should not be used anymore, see the IETF current best practices for details. https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-18#section-2.1.2
As an alternative use a flow with response type code; for clients without possibility to securely store client credentials the authorization code with PKCE flow should be your choice.
From practical perspective (What I understood), The main reason for having Authz code flow is :
Support for refresh tokens (long term access by apps on behalf of User), not supported in implicit: refer:https://www.rfc-editor.org/rfc/rfc6749#section-4.2
Support for consent page which is a place where Resource Owner can control what access to provide (Kind of permissions/authorization page that you see in google). Same is not there in implicit . See section : https://www.rfc-editor.org/rfc/rfc6749#section-4.1 , point (B)
"The authorization server authenticates the resource owner (via the user-agent) and establishes whether the resource owner grants or denies the client's access request"
Apart from that, Using refresh tokens, Apps can get long term access to user data.
There seem to be two key points, not discussed so far, which explain why the detour in the Authorization Code Grant Type adds security.
Short story: The Authorization Code Grant Type keeps sensitive information from the browser history, and the transmission of the token depends only on the HTTPS protection of the authorization server.
Longer version:
In the following, I'll stick with the OAuth 2 terminology defined in the RFC (it's a quick read): resource server, client, authorization server, resource owner.
Imagine you want some third-party app (= client) to access certain data of your Google account (= resource server). Let's just assume Google uses OAuth 2. You are the resource owner for the Google account, but right now you operate the third-party app.
First, the client opens a browser to send you to the secure URL of the Google authorization server. Then you approve the request for access, and the authorization server sends you back to the client's previously-given redirect URL, with the authorization code in the query string. Now for the two key points:
The URL of this redirect ends up in the browser history. So we don't want a long lived, directly usable access token here. The short lived authorization code is less dangerous in the history. Note that the Implicit Grant type does put the token in the history.
The security of this redirect depends on the HTTPS certificate of the client, not on Google's certificate. So we get the client's transmission security as an extra attack vector (For this to be unavoidable, the client needs to be non-JavaScript. Since otherwise we could transmit the authorization code via fragment URL, where the code would not go through the network. This may be the reason why Implicit Grant Type, which does use a fragment URL, used to be recommended for JavaScript clients, even though that's no longer so.)
With the Authorization Code Grant Type, the token is finally obtained by a call from the client to the authorization server, where transmission security only depends on the authorization server, not on the client.