Detailed explanation of OAuth 2.0 authorization authentication

​​​​​​1. Understanding OAuth2.0

1.1, OAuth 2.0 application scenarios

The OAuth 2.0 (Open Authorization) standard is currently widely used in third-party login scenarios. The following are virtual roles, explaining what OAuth2 can do for us, citing Ruan Yifeng’s example in Understanding OAuth 2.0 :

There is a "cloud printing" website, which can print photos stored in Google by users. In order to use the service, users must allow "Cloud Print" to read their photos stored on Google.

The problem is that only with the user's authorization, Google will allow "cloud printing" to read these photos. So, how does "Cloud Printing" get the user's authorization?

The traditional method is that the user tells "Cloud Printing" their Google username and password, and the latter can read the user's photos. This approach has several serious disadvantages.

1) "Cloud printing" will save the user's password for subsequent services, which is very insecure.

2) Google had to deploy password logins, and we know that password-only logins are not secure.

3) "Cloud Printing" has the right to obtain all the data stored by the user in Google, and the user cannot limit the scope and validity period of the "Cloud Printing" authorization.

4) Only by modifying the password, the user can withdraw the power granted to "Cloud Printing". But doing so will invalidate all other third-party applications authorized by the user.

5) As long as a third-party application is cracked, it will lead to the leakage of user passwords, as well as the leakage of all password-protected data.

1.2, noun concept

OAuth was born to solve the above problems. Before explaining OAuth in detail, some basic concepts need to be clarified, and the following concepts are abstracted from the above scenario.

third party application

Third-party application : third-party application , also known as "client" in this article, that is, "cloud printing" in the example in the previous section.

HTTP service provider

HTTP service : HTTP service provider , referred to as "service provider" in this article, that is, Google in the example in the previous section.

resource owner

Resource Owner : Resource owner, also known as "user" (user) in this article.

user agent

User Agent : User agent, in this article refers to the browser.

authentication server

Authorization server : Authentication server, that is, a server specially used by service providers to handle authentication .

resource server

Resource server : resource server, that is, the server where the service provider stores the resources generated by the user . It and the authentication server can be the same server or different servers.

Knowing the above terms, it is not difficult to understand that the role of OAuth is to allow the "client" to obtain the authorization of the "user" in a safe and controllable manner, so that it can interact with the "service provider".

2. OAuth authorization authentication process

2.1. Certification ideas

OAuth sets up an authorization layer between the "client" and the "service provider"  . The "client" cannot directly log in to the "service provider", but can only log in to the authorization layer, so as to distinguish the user from the client. The token (token) used by the "client" to log in to the authorization layer is different from the user's password. When logging in, the user can specify the permission scope and validity period of the authorization layer token.

After the "client" logs into the authorization layer, the "service provider" opens the user's stored data to the "client" according to the scope of authority and validity period of the token.

2.2. Authentication process

The OAuth 2.0 flowchart in the official RFC 6749 document is a bit obscure, so it has been optimized:

1) After the user accesses the third-party application (abbreviation: client), the client requires the user to authorize.

2) The user agrees to authorize the client.

3) The client uses the authorization obtained in step 2 to apply for a token from the authentication server.

4) After the authentication server authenticates the client, it confirms that it is correct and agrees to issue the token.

5) The client uses the token to apply to the resource server for resources.

6) The resource server confirms that the token is correct and agrees to open resources to the client.

The second step in the above is the key, that is, how the user can authorize the client. With this authorization, the client can obtain the token, and then use the token to obtain resources.

Three or four authorization modes

From the previous section, it can be concluded that the user's authorization action to the client is the core, and the client must obtain the user's authorization (authorization grant) to obtain a token (access token) . OAuth 2.0 defines four authorization methods:

3.1. Authorization code mode (authorization code)

The authorization code method means that the third-party application first applies for an authorization code, and then uses the code to obtain a token.

3.2. Simplified mode (implicit)

Some web applications are pure front-end applications with no back-end. At this time, the above method cannot be used, and the token must be stored in the front end. RFC 6749 specifies the second way, allowing tokens to be issued directly to the frontend . This method has no intermediate step of authorization code, so it is called (authorization code) "implicit".

3.3. Password mode (resource owner password credentials)

If you highly trust an application, RFC 6749 also allows users to directly tell the application their username and password. The application uses your password to apply for a token, which is called a "password".

3.4. Client mode (client credentials)

The last method is client credentials, which is suitable for command-line applications without front-ends, that is, tokens are requested under the command line.

4. Detailed Explanation of Authorization Code Mode

4.1. Authorization code mode process

The authorization code mode (authorization code) is the authorization mode with the most complete functions and the most rigorous and safe process. Its characteristic is to interact with the authentication server of the "service provider" through the background server of the client .

Note that this approach is suitable for web applications that have a backend. The authorization code is sent through the front end, the token is stored in the back end , and all communication with the resource server is done in the back end. Such separation of front and back ends can avoid token leakage.

The authorization code mode flow is as follows:

1) The user accesses the client, and the client directs the user to the authentication server.

2) The user chooses whether to authorize the client.

3) Assuming that the user grants authorization, the authentication server directs the user to the "redirection URI" (redirection URI) specified by the client in advance, and attaches an authorization code (each user's authorization code is different) .

4) The client receives the authorization code, attaches the previous "redirect URI", and applies for a token to the authentication server.  This step is done on the client's  background server and is not visible to the user.

5) The authentication server checks the authorization code and the redirection URI, and after confirming that it is correct, sends an access token (access token) and a refresh token (refresh token) to the client.

From the above process description, it can be seen that only the second step requires the user to perform an authorization operation, and the subsequent processes are performed "silently" before the background of the client and the background of the authentication server, which is imperceptible to the user.

The following are the parameters required for the steps above.

4.2. Five steps of authorization code mode process

Step 1

Parameter Description

In the first step, the client applies for the authentication URI, which contains the following parameters:

  • response_type: Indicates the authorization type, a required item , and the value here is fixed as "code"
  • client_id: Indicates the ID of the client, required
  • redirect_uri: Indicates the redirection URI, optional
  • scope: Indicates the scope of authority of the application, optional
  • state: Indicates the current status of the client, and any value can be specified, and the authentication server will return this value intact.
example

Website A provides a link, and the user will be redirected to Website B after clicking, authorizing user data to be used by Website A. The following is a schematic link from website A to website B:

https://b.com/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read 

In the URL above:

response_typeThe parameter indicates that the authorization code is required to be returned ( code);

client_idParameters let website B know who is requesting;

redirect_uriThe parameter is the jump URL after the B website accepts or rejects the request;

scopeThe parameter indicates the required authorization scope (read-only here).

Step 2

In the second step, after the user jumps, the B website will ask the user to log in, and then ask whether to agree to authorize the A website .

Step 3

Parameter Description

In step 3, the server responds with the client's URI, which contains the following parameters:

  • code: Indicates the authorization code, which is required . The validity period of this code should be very short, usually set to 10 minutes, and the client can only use this code once, otherwise it will be rejected by the authorization server. There is a one-to-one correspondence between the code and the client ID and redirection URI.
  • state: If the client's request contains this parameter, the authentication server's response must also contain this parameter exactly.
example

After the user agrees in step 2, website B will jump back to redirect_urithe URL specified by the parameter. When redirecting, an authorization code will be returned, as shown below.

https://a.com/callback?code=AUTHORIZATION_CODE 

In the above URL, codethe parameter is the authorization code.

Step 4

Parameter Description

In step 4, the client requests an HTTP request for a token from the authentication server, including the following parameters:

  • grant_type: Indicates the authorization mode used, which is required , and the value here is fixed as "authorization_code".
  • code: Indicates the authorization code obtained in the previous step, which is required .
  • redirect_uri: Indicates the redirection URI, which is required and must be consistent with the parameter value in step A.
  • client_id: Indicates the client ID, which is required .
example

In the third step, after website A gets the authorization code, it can request a token from website B at the back end.

https://b.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL 

In the URL above:

client_idParameters and client_secretparameters are used to allow B to confirm the identity of A ( client_secretparameters are confidential, so requests can only be sent at the backend);

grant_typeThe value of the parameter is AUTHORIZATION_CODE, indicating that the authorization method used is the authorization code;

codeThe parameter is the authorization code obtained in the previous step;

redirect_uriThe parameter is the callback url after the token is issued.

Step 5

Parameter Description

In step 5, the HTTP reply sent by the authentication server contains the following parameters:

  • access_token: Indicates the access token, which is required.
  • token_type: Indicates the token type, the value is case-insensitive, required, and can be bearer type or mac type.
  • expires_in: Indicates the expiration time, in seconds. If this parameter is omitted, the expiration time must be set in other ways.
  • refresh_token: Indicates the update token, which is used to obtain the next access token, optional.
  • scope: Indicates the scope of authority. If it is consistent with the scope applied by the client, this item can be omitted.
example

In step 4, after website B receives the request, it will issue a token. The specific method is to redirect_urisend a piece of JSON data to the specified URL:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read","uid":100101,"info":{...}
} 

In the above JSON data, access_tokenthe field is the token, and website A got it at the backend. Note: It is explicitly specified in the HTTP header that it must not be cached.

5. Token transfer method

When the client (third-party application) gets a token to access the resource server, it can use this token to access resources.

After the third-party application gets it , how to send it to the resource server is not defined in the RFC6729 document, but  is defined independently in access_tokena separate  RFC6750 document. Here is a brief introduction, mainly in three ways:

1.URI Query Parameter
2.Authorization Request Header Field
3.Form-Encoded Body Parameter

5.1. Transfer of request header parameters

Authorization Request Header Field, because in the HTTP application layer protocol, there is a Request Header specifically defined for authorization, so this method can also be used:

GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM 

Among them, "Bearer" is the fixed header information in front of access_token.

5.2. Form encoding transmission

There is an additional requirement to use the Request Body method, that is, the Request Header Content-Typemust be fixed application/x-www-form-urlencoded. In addition, there is a restriction that  GET access cannot be used  . This is easy to understand, after all, GET requests cannot carry Request Body.

POST /resource HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

access_token=mF_9.B5f-4.1JqM 

5.3. URI request parameter passing

URI Query Parameter, this way of use should be the most common way, very simple, such as:

GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1
Host: server.example.com 

Add an access_token parameter after the Url that we request the protected resource. Another requirement is that the Client needs to set the following Request Header  Cache-Control: no-store to prevent the access_token from being logged by the Web middleware, which is a consideration for security protection.

5.4. Token refresh

In order to prevent the client from using a token for unlimited times, the token generally has an expiration time limit. When the token is about to expire, it needs to obtain the token again. If the authorization process of the authorization code is repeated, it will be very bad for the user experience. So OAuth 2.0 allows users to automatically renew tokens.

The specific method is that when website B issues tokens, it issues two tokens at once, one for obtaining data and the other for obtaining new tokens (refresh token field). Before the token expires, the user uses the refresh token to send a request to renew the token.

https://b.com/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN 

In the URL above:

grant_typeThe parameter is to refresh_tokenindicate that the token is required to be updated, and the value here is fixed as refresh_tokena required item;

client_idParameters and client_secretparameters are used to confirm identity;

refresh_tokenThe parameter is the token used to update the token.

After the B website is verified, a new token will be issued.

Note:  The refresh token obtained by the third-party application server must be stored in the server, and the new token must be obtained again through the background to ensure the confidentiality of the refresh token.

Six, OAuth2 security issues

6.1. CSRF attack

When the application used OAuth2 in the early stage, many related security vulnerabilities broke out. In fact, after careful analysis, it will be found that most of them are caused by not strictly following the security-related guidelines of OAuth2. Search for related vulnerability events by yourself.

In fact, OAuth2 has already done a lot of security considerations at the beginning of the design, and added some security specification guidance in RFC6749. for example:

1. Authorization server is required to perform effective client verification;

2. Secure storage of sensitive information such as client_serect, access_token, refresh_token, code (not to be disclosed to third parties), security of transmission channel (TSL requirements);

3. Maintain the binding between refresh_token and third-party applications, and refresh the invalidation mechanism;

4. Maintain the binding of Authorization Code and third-party applications, which is why the state parameter is recommended to prevent CSRF attacks;

5. Ensure that the above-mentioned various token information cannot be guessed to prevent it from being guessed; security is no small matter, and this aspect must be jointly prevented by all parties (open platform, third-party developers).

6.2. Attack process

Suppose there are user Zhang San, attacker Li Si, a third-party "Cloud Printing" application (which integrates third-party social account login and allows users to bind social accounts with accounts in "Cloud Printing"), and OAuth2 services Provided by Google.

step 1

The attacker Li Si logs into the "Cloud Printing" website and chooses to bind his Google account

step 2

The "Cloud Printing" website redirected Li Si to Google. Since he had logged into Google before, Google directly showed him the page whether to authorize "Cloud Printing" to visit.

step 3

After Li Si clicks "Agree to Authorize", he intercepts Authorization codethe HTTP response containing parameters returned by the Google server.

step 4

Li Si carefully constructed a web page, which will trigger the "Cloud Printing" website to initiate a token application request to Google, and the parameters in this request Authorization Codeare exactly the code intercepted in the previous step.

step 5

Li Si puts this Web page on the Internet, and waits for or tricks the victim Zhang San to visit.

step 6

Zhang San logged into the "Cloud Printing" website before, but he didn't bind his account with other social accounts. After Zhang San visited the web page prepared by Li Si, the token application process was successfully triggered in Zhang San's browser, and the "Cloud Printing" website obtained it from Google, but the token and the users obtained through access_tokenit The information was all from the attacker Li Si.

step 7

The "Cloud Printing" website binds Li Si's Google account with Zhang San's "Cloud Printing" account. From then on, Li Si can use his Google account to log in to Zhang San's "Cloud Printing" website through OAuth account, blatantly impersonating Zhang San’s identity to perform various operations.

On the whole, the timing diagram of this CSRF attack should look like this:

As can be seen from the above figure, the key point that causes the CSRF attack vulnerability problem is that the OAuth2 authentication process is divided into several steps to complete, in the fourth step in the flow chart of the authorization code mode process in the previous chapter Among them, when a third-party application receives a GET request, in addition to knowing the current user's cookie and URL Authorization Code, it is difficult to distinguish whether the request is the user's own will or the attacker forged the user's identity. ask.

Therefore, the attacker can use tricks to prepare a Authorization Coderequest containing his own in advance, and let the victim's browser complete the subsequent token application process.

6.3. Solutions

It is actually very easy to prevent such attacks. As a third-party application developer, you only need to add parameters in the OAuth authentication process stateand verify its parameter values. The details are as follows:

  • When redirecting the user to the authorization interface of the resource authentication server, generate a random string for the current user, stateadd it to the URL as a parameter, and store a copy in the session.
  • When the third-party application receives the request returned by the resource service provider Authorization Code, it verifies the received stateparameter value. If it is a correct and legal request, the parameter value received at this time should be exactly the same as the parameter value generated for the user mentioned in the previous step state(stored in the current user's session), otherwise it is an abnormal request.
  • stateThe parameter value needs to have the following characteristics: * Unpredictability: sufficiently random, making it difficult for an attacker to guess the correct parameter value * Correlation: The stateparameter value and the current user session (user session) are interrelated * Uniqueness: The parameter value generated by each user and even each request stateis unique* Timeliness: stateOnce the parameter is used, it will be invalid immediately

stateThe parameter is not a mandatory parameter in the OAuth2 authentication process, so early third-party application developers easily ignored its existence when integrating OAuth2 authentication, making the application vulnerable to CSRF attacks. So we must pay attention to this security issue.

Security is shared by both parties, requiring both third-party applications and resource service providers to strictly abide by security regulations. For example, in the OAuth2 API of QQ Internet, the state parameter is a mandatory parameter, and the authorization interface is an encrypted channel based on HTTPS, etc.; as a third-party developer, when using and consuming these services, they should also pay attention to the loopholes in security.

Reposted from: Detailed Explanation of OAuth 2.0 Authorization Authentication_oauth2.0_GJ_ia's Blog-CSDN Blog

Guess you like

Origin blog.csdn.net/fuhanghang/article/details/131394196