Microservice Architecture - Service Gateway (Gateway) - Authorization Authentication (Distributed Session Alternative)

Authorization authentication - distributed session alternative

Earlier we learned about the filters of the Gateway component. In this section, we will discuss a specific use case of Gateway in a distributed environment-user authentication.

1. Traditional single application user authentication

Since we started learning JavaEE, we have been brainwashed into a standard method of authority verification, which is to save the user's login status in the HttpSession, such as saving a pair of key-value values ​​​​to the session after successful login, key It is userld and value is the real ID of the user background.

Then create a ServletFilter filter to intercept resources that need to be logged in to access. If the key userld cannot be found in the server session corresponding to this request, it means that the user has not logged in. At this time, you can directly refuse the service and redirect to User login page.

Everyone should be familiar with the session mechanism. It and cookies are interdependent. Cookies are information stored in the user's browser, while sessions are stored on the server side. When the browser initiates a service request, it will bring a cookie, and the server will get the corresponding session according to the jsessionid in the cookie after receiving the Request.

Since we only start one server, the session saved after login is always in this server, and all the information in the session can be easily obtained. Using this method, we have completed various coursework and graduation projects along the way. As a result, when I got to work, I found that it didn't work, because all applications are deployed in clusters, and the sessions saved on one machine cannot be synchronized to other machines. Do we have any mature solutions?

2. Solutions in a distributed environment

2.1) Synchronous session

Session replication is the easiest solution to think of first, we can copy the session in one machine to other machines in the cluster.

For example, Tomcat also has a built-in session synchronization solution, but this is not a very elegant solution, and it will bring the following two problems:

Timing problem: Synchronization takes a certain amount of time, and we cannot guarantee the timeliness of session synchronization. That is to say, when two requests initiated by the user land on different machines, the information written into the session by the previous request may not be available yet. Synchronized to all machines, the latter request has already started to execute business logic, which will inevitably lead to dirty phantom reading.

Data redundancy: All servers need to save a full set of sessions, which generates a lot of redundant data

2.2) Reverse proxy: bind IP or consistent Hash

This solution can be done at the Nginx gateway layer. We can specify that requests for certain IP segments fall on a specified machine, so that the session always exists on only one machine, but compared to the previous method of session replication , the way of binding IP has more obvious flaws:

Load balancing: In the case of binding IP, the load balancing strategy cannot be applied at the gateway layer, and if a server fails, it will have a great impact on the visiting users of the specified IP segment. For the gateway layer, the routing rule configuration of this scheme is also extremely troublesome;

IP change: Many network operators will switch user IPs from time to time, which will cause requests after changing IPs to be routed to different service nodes for processing, so that the previously set session information cannot be read.

In order to solve the second problem, routing can be done through a consistent Hash routing scheme, such as doing Hash according to the user ID, and the different Hash values ​​fall on different machines to ensure a sufficiently even distribution, thus avoiding IP switching problem, but it still cannot solve the load balancing problem mentioned in the first point.

2.3) Redis solution

This solution solves most of the problems mentioned above. The session is no longer stored on the server, but is stored in redis instead, and all servers write/read cache information to redis.

At the Tomcat level, we can directly enter the tomcat-redis-session-manager component to replace the session component at the container level with a redis-based grouping, but this solution is closely bound to the container.

Another more elegant solution is to use spring-session to manage sessions in redis. Although this scheme is separated from the specific container, it is still a session-based user authentication scheme. This kind of session scheme has been eliminated in microservice applications.

2.4) Alternatives to Distributed Session

Let's leave the session behind and look at the two popular authentication methods:

2.4.1)OAuth 2.0

Everyone must have used the popular third-party login. For example, we can log in to the online system of an application by scanning the QR code on WeChat, but this application does not know my WeChat username and password. This is the first part we will introduce. An authentication scheme - OAuth 2.0.

OAuth 2.0 is an open authorization standard protocol, which allows users to allow third-party applications to access the user's specific private resources in a service, but does not provide account and password information to third-party applications.

In the above example, WeChat is equivalent to a third-party application. We use OAuth 2.0 as an example to log in to a third-party application via WeChat:
insert image description here

  • Auth Grant: In this step, CIient initiates an Authorization Request to the WeChat system (for example, by scanning the code in WeChat to authorize), and obtains the Auth Grant after the identity verification is successful;
  • Get Token: The client takes the Auth Grant obtained from WeChat and sends it to the authentication service referenced by the third party in exchange for a Token, which is the token needed to access third-party application resources;
  • Access resources: In the last step, the client brings the Token token when requesting resources, and the server returns the specified resource after verifying that the token is true and valid.

We can use the built-in spring-cloud-starter-oauth2components in Spring Cloud to build OAuth 2.0 authentication services. The OAuth 2.0 protocol also involves many complex specifications, such as roles, client types, and authorization modes. In this section, we will not delve into the implementation of OAuth 2.0 for the time being. Let's first look at another lighter authorization scheme: JWT authentication.

2.4.2) JWT authentication

JWT is also a Token-based authentication mechanism. Its basic idea is to exchange a user name + password for an Access Token.

2.4.2.1) Authentication process

Compared with OAuth 2.0, its authentication process is simpler, and its basic flow is as follows:

1. Username + password access authentication service

  • Verification passed: the server returns an Access Token to the client, and saves the token somewhere on the server for subsequent access control (it can be saved in a database or Redis);
  • Verification failed: Token not generated.

2. The client uses the token to access resources, and the server verifies the validity of the token

  • The token is wrong or expired: intercept the request and let the client reapply for the token;
  • The token is correct: release is allowed
2.4.2.2) Contents in Access Token

JWT's Access Token consists of three parts, namely Header, Payload and Signature. Let's see what information these three parts contain:

Header: The header declares the type of Token (JWT type) and the encryption algorithm (HS256);

{
  'typ': 'JWT',
  'alg': 'HS256'
}

**Payload:** This paragraph contains quite a lot of information. You can define a series of attributes such as the Token issuer, issuance and expiration time, and effective time. You can also add custom attributes. The same can be done when the server receives the Token Verify the information included in the Payload. For example, the issuer of a certain Token is "Feign-API". If a certain interface can only allow Tokens issued by "Gateway-API", then it can be used for authentication services. Add the judgment logic of lssuer.

Signature: It will use Header and Payload and a key to generate visa information. This step will use the encryption algorithm we specified in the Header to encrypt

At present, there are many open source components that implement JWT. If you decide to use this solution, you only need to add any open source JMT implementation dependencies to the POM file in the project, and then call this component to complete the encryption and decryption.

Guess you like

Origin blog.csdn.net/jianghao233/article/details/130055847