The Chinese name of the request is an open license agreement, the name you taste carefully, it is a licensing agreement, any site to implement the agreement can be under the condition of the user agrees to give some here at their registration granted corresponding to the user of the application of some resources on this web site, and the access token is commonly used in.

Examples of practical applications

When you go to LeetCode and log in, the following page will pop up

Here we have two options, one is to directly register an account, the other is to choose a third party login, such as QQ login, this third party login uses OAuth.

There are a few points to emphasize about this second approach:

  • The number of your accounts has not been reduced at all. You still have both Leetcode and QQ accounts, but QQ provides OAuth protocol. You authorize LeetCode to obtain your information in QQ, and LeetCode uses this information to create your account in LeetCode. Your account in LeetCode will not be stored in QQ at all, which is similar to the fact that you need to take your ID card to register an account in the relevant organization in real life. The organization will use your ID card to search your information in the public Security Bureau system, and then use this information to create your account in the organization. When you give the agency an ID card, it’s like giving it permission to go to the public security Bureau and manipulate your information.
  • OAuth protocol is only an authorization protocol, and the above process is called third-party authorization login. The action of login is not stipulated in OAuth protocol, that is to say, only OAuth can not complete the action of authorization login, and OAuth is not only used for third-party login. Although we use third party authorization to log in to OAuth most of the time, think outside the box.

The development of login methods

User Name Password

When we started with server-side rendering and static pages, we only authenticated by username and password, which is the basis of all authentication, and will continue to be based on this method for the most part.

This method works well in the beginning. The site gives you a login page, and when you login successfully, you are sent back to another page from the server. When you get this page, it means that you have logged in, and your identity has been written on the page before you return, but you can’t see it.

But the biggest problem with this is that once you close the page, the next time you open it, you have to log in again, which is a poor user experience. So we started to think of a way to save the user’s login state? And that’s where the second approach comes in, sessions and cookies.

The Session and cookies

In this way, after the user logs in successfully for the first time, the user’s information is saved in the session and stored in the server, and then a sessionId is generated to mark the session and returned to the front end through the set-cookie header. In this way, due to the implementation decision of the browser, each same-origin request will automatically carry the cookie under the source, which also carries the sessionId. In this way, the server only needs to check the sessionId in the cookie and verify its validity to find the user information.

Basically, browsers know and probably the whole world knows. I recommend taking a closer look at the same origin policy. It’s not as strict as you might think, but I’ve learned a few things about it lately:

  • The same-origin policy generally only restricts requests such as XMLHttpRequest, such as Ajax. Requests made directly from the address bar are unrestricted, and it is still being explored whether requests redirected to the address bar are restricted.
  • Cross-domain write operations such as form submission, redirection, and so on are generally unrestricted
  • Cross-domain resource embedding is generally unlimited.
  • Cross-domain reads are generally not allowed, but can be broken by the previous entry, such as using the script tag to load scripts across domains
  • Scripts in different domains cannot manipulate the DOM.

The key thing is that the browser’s same-origin policy doesn’t limit requests made directly from SRC, and cookies from the same domain will be automatically taken whenever you request a link.

Here’s a classic example, if you log in to a bank website and store your sessionid in a cookie, and before the cookie expires, you open an attacker’s website with an img tag and its SRC attribute is bank.com/tran/1000, Since it is SRC, the browser will automatically initiate this request. Although there will be no picture returned, the request has already been sent, and it will automatically bring the cookie of the bank that has not expired. Because the browser sees that the address you requested is the bank, it will automatically bring it for you.

The above example is a relatively simple CSRF attack.

The main purpose of this example is to show that cookies are not secure, even with the same origin policy.

And with the development of distributed systems, if you store identity this way, you have to maintain a copy of identity on each server, and keep it consistent.

So for those two reasons, we were wondering, is there a way that we can both throw the identity back to the front end, so that every time the front end comes in with the identity, I just verify that I gave it to him, and make that safer? So we created a Token. These are also two characteristics of token, one is stored in the front end, the other is generated by the server, it is generally not stored in the cookie.

Token

Just now we said that Token is the proof of our identity generated by the server and stored in the front end, so how can we ensure its security? An old practice is to insert your token at every place you submit a request before returning if your page is rendered on the server, so that the token is not stored in a cookie, and cross-domain scripts cannot manipulate the DOM to get your token.

However, it seems to be back to the beginning. Once the page is closed, the token is gone, and it consumes a lot of money.

Another way is to put the token in the HTTP header, the X-CSRF header.

There are also many ways to use tokens, which are not the focus of this time and will not be explained in detail.

SSO and request

When we identity after getting better solve all the problems, and the emergence of a new problem, that is along with the increase in applications, we need to remember more and more accounts, we need a way to help us remember all the account or write an account of it, the second option is to SSO, it has a variety of implementation, One of them is today’s topic, OAuth.

Before we get into this topic, let’s define a few keywords:

User: User

User Agent: Indicates the User Agent, such as the browser

Consumer: Information Consumer, such as Leetcode

Service Provider: it is divided into two parts, namely Identity Provider (IDP), such as QQ, and Resource Provider (Resource Provider), but the two are generally the same.

So:

  • SSO wasn’t invented to solve security or process problems in logins, it was invented to help us remember fewer accounts, and OAuth is just the foundation of one of its implementations.
  • OAuth is only responsible for user authorizing consumer to SP to manipulate some resources belonging to user, but in SSO, it is used to create an account in Consumer after SP obtains user information, so that next time user is authenticated in SP, it is authenticated in consumer.
  • The identity and permissions of the User in the consumer have nothing to do with OAuth. This is between them, not OAuth or SSO. Authentication between them will revert back to the first three methods. SP does not care about or store User’s identity or permissions in consumer.
  • OAuth alone cannot complete the entire process of authorized login.

Take a look at the request for OAuth in the SSO process

This picture is the request involved in the front end of logging in Leetcode with QQ captured by me. It can be roughly divided into the following steps:

  • Go to the QQ authentication server to pull the authorization page, the parameters have some parameters generated by leetcode server for the next authorization request, only with these parameters, can pass the AUTHENTICATION of QQ authentication server and return to the authorization page, at the same time, the next request of the authorization page will need these parameters
  • After authorization is selected, a second request will be sent, including some parameters defined in OAuth protocol and parameters required by QQ itself.
  • After the second request reaches QQ, it passes the verification and returns a 302. Location is the redirect_URI in the second request parameter, and then the code and state generated by QQ are combined in the parameter.
  • When the browser gets the 302 back, it pulls out the location to send the request, so the location is usually its own background.
  • After the backend receives the request, it takes out the code to exchange for token on QQ

That’s what the OAuth protocol does. Now do we have an account in LeetCode? No, the leetcode account will be created after leetcode takes the token to QQ to exchange the identity information

To illustrate some of the details of the OAuth2.0 design, use the authorization code pattern

A request is the first request, B is the second authorization request, C is the return of B, the status code is 302, location is redirect_URI, ok? Code =XXX&state=XXX, the browser received the request for C’s location again, the request went to the background of Leetcode, the background got the code, combined with some parameters to QQ to exchange the token.

You may have a lot of questions here:

What do these parameters mean:

Redirect_uri: domain name that a consumer enters when SP applies for third-party authorization to log in to the service. It is usually the domain name of its own server.

Client_id: unique ID of a consumer generated by SP after SP applies for third-party authorization to log in to the service.

Client_secret: Consumer after SP applies for third-party authorization to log in to the service, SP generates the unique certificate of the consumer. Only when the id and secret are given at the same time, can you prove that you are a consumer

Scope: The permission you want to apply for is generally stipulated by SP.

State: a random string generated by the consumer itself

Code: the code SP returns to the browser after the user authorizes the token. The consumer can exchange this code for token

Access_token: The end purpose.

Why send a redirect_URI to the IDP in the first place?

The first step is to verify that the redirect_URI is the same as the one you set in IDP. The second step is to verify that the redirect_URI is the same as that set in IDP. This step returns the token.

Why go all the way around, why do YOU need to change the access_token one more step?

Let him be a tool man. Let him apply for an authorization code from a third party for his background, and then give the authorization code to his background, and then his background applies for a token from a third party with this code. After that, he doesn’t tell the browser what the token is. So browser guys never saw token the whole time.

What does Secret do?

The reason is that IDP does not trust anyone, so they trust the secret they give out. Because redirect_URI is a domain name, the destination depends on the IP address. If the domain name is correct, but the domain name is pointed to the attacker’s OWN IP, the attacker will receive the token. So how you change this DNS pointer is going to involve DNS contamination, because DNS is going to cache layers, but you have time, so if you keep broadcasting to the router or the host that I’m Leetcode, I’m Leetcode, you’re going to be considered leetcode in that area of the network. But if you have secret, even if you come to IDP with code, IDP will not give token without the secret I gave you. Client_id indicates who you are, IDP will trust you and give you token only if you give client_secret, so this secret is very important, our background will not trust browser partners, so our browser partners never touch secret.

What’s the use of State?

It is similar to defending CSRF, ensuring the consistency of requesting devices, but unlike CSRF, which forgery the request of the victim, but lets the victim log in his own account, wouldn’t it be beautiful if the victim saved a Bitcoin account in it? The specific implementation is that after the attacker logs in, he normally applies for login, but after returning 302 to IDP, he blocks the request and prevents the browser from sending the request to his background. Then he sends the request link with code to the victim, and the victim can get access_token after clicking in. If you upload sensitive information without paying attention to whether the account is your own, you will be happy. If there is state, the background will generate a random string for different devices and send it to the front end. Even if the attacker sends the request to the victim, he does not know the state in the victim’s device. Once the background sees that your state is different from the original one, it will directly throw the request away. Of course, to say that the attacker stole your state from a huge Internet request, that is also absolutely, this belongs to the fixed point blasting, is to mess with you, that this person is probably already mixed in your side.

Why are two tokens returned at the end?

Because one represents who you are and the other represents what you can do, what you can do can be changed at any time by the administrator, but who you are is fixed, and generally the access_token expiration time is relatively short, if I use it, I can not let the user log in again, that is not back to the starting point?

Other modes in OAuth2.0

Simplify the model

This method is different from the authorization code mode. It applies to situations where there is no server, such as mobile applications. The front end directly gets the token from SP, but it should be noted that the token is not spelled with “? After, but after the “#”, thus effectively reducing the risk of disclosure.

Password mode

In the Resource Owner Password Credentials Grant mode, users provide their user names and passwords to clients. The client uses this information to request authorization from the “service provider.”

In this mode, the user must give his password to the client, but the client cannot store the password. This is usually used when the user has a high degree of trust in the client, such as when the client is part of the operating system or is produced by a well-known company. Authentication servers can only consider using this mode if other authorization modes cannot be implemented.

Client mode

The Client Credentials Grant allows clients to authenticate to the service provider in their own name, not the user’s. Strictly speaking, the client-side pattern is not the problem that the OAuth framework addresses. In this model, users register directly with the client, and the client requests services from the “service provider” in its own name, with no authorization issues.

OAuth1.0

A brief introduction to 1.0 and why it evolved into 2.0

The biggest difference is that there are two more steps, i.e. 1.0 will first apply for an unauthenticated request_token from SP (code 2.0 can be used as an example), and then the purpose is to change the request_token to authenticated state. The request_token can then be exchanged for the access_token.

Adding this step can cause problems, such as session fixation

Also, for mobile or client applications, the redirection step is not possible, only to throw out a connection and let the user open a browser and paste it into the next step. This gives the attacker a great opportunity.

As a result, version 1.0 had major security issues and was a poor experience for non-Web applications, so 2.0 was introduced.

For example, 2.0 simplified mode is to adapt to the client application, interested in their own to understand.

1.0 a

In order to fix the security problems in 1.0, he proposed 1.0A, which mainly made the following changes:

  • When a Consumer applies for a Request Token, oAUTH_callback must be passed. When a Consumer applies for an Access Token, oAUTH_callback is not required. Through the delivery time of oAUTH_callback, oAUTH_callback can participate in the signature, so as to avoid the attacker impersonating OAUTH_callback.

  • When a Service Provider redirects a User to a Consumer after obtaining User authorization, it returns oauth_verifier, which is used when the Consumer applies for an Access Token. An attacker cannot guess its value.

References:

[sunra.top/2019/11/16/… sunra.top/2019/11/16/… and OIDC/] : OAuth, OIDC

Sunra. Top / 2020/03/27 /… : Routing protocol

Sunra. Top / 2019/09/15 /… : ARP principles and defense

www.jianshu.com/p/0db71eb44… : Example of OAuth authentication process

www.chrisyue.com/security-is… : Security considerations in OAuth2.0

www.cnblogs.com/linianhui/p… : OIDC document

www.zhihu.com/question/19… : OAuth1.0 differs from 2.0

Docs. Azure. Cn/useful – cn/activ… : OIDC + AAD

www.sciencedirect.com/science/art… : Security problems in cloud services

Developer.mozilla.org/zh-CN/docs/… : Same-origin policy