1 background

Some time ago, I participated in the migration of the old project. When cooperating with the migration of back-end interface, the two projects adopted different login schemes, so I encountered the problem that the cross-domain login modes could not be shared. After coordination, the old project eventually deployed the migrated page under the new project’s specified gateway and used the SSO login scheme of the new project. The login mode sharing problem encountered in the migration triggered my thinking and learning of SSO. If you find anything wrong in this article, please correct it immediately ~ 🙈

2 Login maintenance mode

2.1 JWT (Json Web Token)

What is 2.1.1?

JWT is an open JSON format token storage standard. It defines a secure and compact way to save data and verifies the validity of tokens through signatures. Signature algorithms such as HMAC, RSA, and ECDSA are supported.

JWT is usually used to store login information. Compared with the traditional session scheme, it has the advantage that the server does not need to maintain login state and does not need to rely on third-party storage (such as redis and memcached), so JWT is stateless.

But there are drawbacks. Because it is maintained only on the client, the server cannot easily clear the login state. Compared with the traditional session scheme, it only needs to clear the session. You might say that you can simply delete the token and log out. In fact, this is just a fake logout, and if the user gets the same token again, it will still be considered logged in.

2.1.2 Data Structure

The JWT is composed of header, payload, and signature. It looks like this: header.paypay.signature.

  • Header: This section is a JSON object that describes the metadata of the JWT, usually something like this.
{"alg": "HS256", // algorithm of signature, default is HMAC SHA256 (HS256) "typ": "JWT" // indicates the type of the token. JWT tokens are written as JWT} by default.Copy the code
  • Playload: This section is also a JSON object that holds the actual data that needs to be passed. JWT specifies seven official fields to choose from. In addition to the official fields, you can also customize some other fields.
Iss (Issuer) : exp (expiration time) : expiration time sub (subject) : aud (audience) : NBF (Not Before) : iAT (Issued At) : Issue time JTI (JWT ID) : numberCopy the code

⚠️ JWT is unencrypted by default and anyone can read it, so don’t put secret information in this section. The JSON object is also converted to a string using the Base64URL algorithm.

  • Signature: This part is the Signature of the first two parts to prevent data tampering. First, you need to specify a secret. This key is known only to the server and cannot be disclosed to users. Then, using the signature algorithm specified in the Header (HMAC SHA256 by default), generate the signature as follows. The server receives the JWT and compares the signature to determine whether the Token has been modified.
HMACSHA256(

  base64UrlEncode(header) + "." +

  base64UrlEncode(payload),

  secret)
Copy the code
  • Base64Url: This algorithm is basically similar to the Base64 algorithm, with some minor differences. JWT as a token may be placed in a URL in some cases (such as api.example.com/?token=xxx). Base64 has three characters+,/and=, has a special meaning in the URL, so it should be replaced:=Omitted,+replace-./replace_. This is the Base64URL algorithm.

2.1.3 characteristics

  1. JWT is not encrypted by default, but it can be encrypted. Sensitive data cannot be written to the JWT without encryption. However, after the original Token is generated, it can be encrypted again with the key.
  2. JWT can be used not only for authentication, but also for information exchange. Using JWT effectively can reduce the number of times the server queries the database.
  3. The biggest drawback of JWT is that since the server does not store session state, there is no way to invalidate a token or change the token’s permissions during use. That is, once a JWT is issued, it remains valid until expiration, unless the server deploys additional logic.
  4. The JWT itself contains authentication information, and if it is disclosed, anyone can gain full access to the token. To reduce theft, the JWT validity period should be set short, and JWT should not use HTTP for explicit code transport, but HTTPS for transport. For some important permissions, the user should be authenticated again.

2.2 the Session & cookies

What is 2.2.1?

(1) the Cookie

A Cookie is a small piece of data that the server sends to the user’s browser and keeps locally. It is carried and sent to the server the next time the browser makes a request to the same server. Typically, it is used to tell the server whether two requests are from the same browser, such as to keep the user logged in. Cookies make it possible to record stable state information over stateless HTTP protocols.

There are two types of cookies: Session cookies and Persistent cookies. If a Cookie does not contain an expiration date, it is regarded as a Session Cookie. Session cookies are stored in memory, never written to disk, and are permanently lost thereafter when the browser is closed. If a Cookie contains an expiration date, it is considered a persistent Cookie, after which the Cookie will be deleted from disk.

Main uses:

  • Session state management (such as user login status, shopping cart, game score, or other information that needs to be logged)
  • Personalization (such as user-defined Settings, themes, etc.)
  • Browser behavior tracking (e.g. tracking and analyzing user behavior, etc.)

(2) the Session

Session represents a Session between the server and the client. The Session object stores properties and configuration information required for a specific user Session. This way, variables stored in the Session object will not be lost when the user jumps between Web pages of the application, but will persist throughout the user Session.

Common misconception: Sessions don’t disappear by closing the browser. For sessions, unless the application tells the server to delete a Session, the server will keep it until the Session expires. In most cases the browser does not notify the server before closing the web page, so the server does not know that the browser is closed. The reason for this illusion is that most session mechanisms use session cookies to store the session ID, which disappears when the browser is closed and the original session cannot be found when the server is connected again. If the cookie set by the server is saved on the hard disk, or the HTTP request header sent by the browser is rewritten in some way to send the original session ID to the server, the browser can still open the original session again.

2.2.2 Relationship between Session and cookie

(1) Relationships

When the server receives the request for the first time, it creates a Session space (the Session object is created), generates a Session ID, and passes the set-cookie in the response header: The JSESSIONID=XXXXXXX command sends a response to the client requesting Cookie Settings. After receiving the response, the client sets a Cookie with JSESSIONID=XXXXXXX on the local client. The expiration time of the Cookie is the end of the browser session. When the client sends a request to the same website each time, the request header will carry the Cookie information (including the sessionId), and then the server obtains the value named JSESSIONID by reading the Cookie information in the request header to obtain the session ID of the request.

(2) Differences

  1. Security: Since sessions are stored on the server and cookies are stored on the client, the possibility of Cookie theft is higher than Session theft.
  2. The value types are different: Cookies only support string data. If you want to set other types of data, you need to convert them into strings. Session can store any data type.
  3. Different storage sizes: The data stored by a single Cookie cannot exceed 4K, and the data stored by a Session is much higher than that stored by cookies. However, if there are too many visits, too many server resources will be occupied.

2.2.3 Mode of Carrying Session ids

  • Cookie: The session ID can be saved using cookies. In this way, the browser can automatically send this id to the server according to rules during interaction.
  • URL rewriting: Since cookies can be artificially disabled, there must be other mechanisms to pass the session ID back to the server even if cookies are disabled. A technique commonly used is URL rewriting, where the session ID is appended to the URL path. There are two ways to do this. Either as additional information about the URL path, or as a Query string appended to the URL. The network remains state throughout the interaction and must include this session ID after every possible path requested by a client.

3 Single Sign-on (SSO)

3.1 What is SSO

Single sign-on (SSO) is a method to provide access control for many interconnected but independent software systems.

Single sign-on (SSO) occurs when a user logs in to one application and then automatically logs in to another application, regardless of the platform, technology, or domain the user is using. For example, if you log into Google services like Gmail, you are automatically authenticated by YouTube, AdSense, Google Analytics and other Google apps. Similarly, if you quit Gmail or other Google apps, you will automatically quit all apps; This is called a single point of cancellation (SLO).

3.2 the CAS

What is 3.2.1?

Central Authentication Service (CAS) is an enterprise-level and open source project initiated by Yale University. It aims to provide a reliable single sign-on (SSO) solution for Web application systems. The image below is from Wikipedia.

Roles in SSO system:

  • User: indicates the platform User
  • Web application: platform for accessing the CAS SSO service
  • SSO Authentication Center (CAS Service) : provides the CAS SSO service

3.2.2 Confusing concepts

  • TGT: Ticket Grangting Ticket

A TGT is a login ticket issued by CAS for users. With a TGT, users can prove that they have successfully logged in to CAS. The TGT encapsulates the Cookie value and the user information corresponding to this Cookie value. When an HTTP request arrives, CAS queries the cache for TGTS based on the Cookie value (TGC). If there is a TGT, CAS believes that the user has logged in.

  • TGC: Ticket Granting Cookie

The CAS Server generates a TGT and stores it in its own Session. The TGC is the unique Session ID (SessionId) and stored in the browser in the form of cookies. The TGC is used by the CAS Server to identify the user’s identity.

  • ST : Service Ticket

An ST is a ticket issued by CAS for users to access a service. When a user accesses the Service and the service finds that the user does not have an ST, the user is required to obtain the ST from CAS. The user sends an ST request to CAS. When CAS discovers that the user has a TGT, the CAS issues an ST and returns the ST to the user. The user uses the ST to access the Service, and the Service uses the ST to the CAS for authentication. After the authentication succeeds, the user is allowed to access resources. Unlike access_token in OAuth, ST can only be used once and then expire.

👇PGTIOU, PGT, PT are the content of CAS 2.0 agent mode, interested students can learn by themselves.

  • PGT: Indicates a Proxy Granting Ticket

Proxy credentials of the Proxy Service. A PGT object is generated using CAS and cached in PGTIOU.

  • PGTIOU: Proxy Granting Ticket I Owe You

Yes After the serviceValidate interface of CAS verifies the ST successfully, CAS generates an XML message verifying the ST success and returns it to the Proxy Service. The XML message contains PGTIOU. After receiving the XML message, the Proxy Service parses the VALUE of PGTIOU. Use this as the key, find the VALUE of PGT in the map, assign pgtId to the Assertion object representing user information, and delete it in the map.

  • PT : the Proxy Ticket

It is a ticket for the user to access the Target Service (back-end Service). If the user accesses a Web application, the Web application requires the browser to provide ST, and the browser uses cookies to obtain ST from CAS. Instead, the browser accesses the proxy Service interface and obtains a PT by using the PGT of the Proxy Service to access the application.

3.2.3 Single Sign-on (SSO) & Single Sign-off (SLO)

3.2.3.1 Login process

The following is the login sequence diagram of CAS official website, which can help us understand better. We suggest that we have a closer look

3.2.3.2 Single sign-off

In addition to SSO, CAS also provides the SLO (single sign-off) function. The CAS Service and Client Service each maintain a login state, so the login state between the CAS Service and Client Service is separated. How can we implement the SLO?

Since the official did not give a detailed flow chart, so I drew one according to my own understanding, for your reference ~

Main process:

  1. After a platform requests to log out, the CAS login page with the Service field is first redirected in query.
  2. Sends a request to the CAS Server with the Service Query field and TGC.
  3. The CAS Server queries the login information through the TGC and traverses the requests for each access platform/logoutInterface;
  4. When the login status of all services is cleared, the single sign-on (SSO) succeeds.

3.3 request

What is 3.3.1?

In OAuth “O” is short for Open, meaning “Open”. OAuth is an open network standard for authorization. OAuth allows users to grant third-party applications access to their data stored on other services without requiring them to provide a username and password. A direct example is that third-party apps use wechat or QQ to log in, and OAuth is used for these authorized logins.

3.3.2 Definitions of nouns

  • Third-party application: third-party application client, which is equivalent to the current App requiring authorization
  • HTTP service: the service provider refers to wechat and QQ
  • Resource Owner: User/Resource Owner. This article refers to the user registered in wechat
  • Authorization Server: A server that issues access tokens to clients after resource owners authorize them
  • Resource Server: A server on which service providers store user-generated resources. It can be the same server or a different server from the authentication server.

3.3.3 Four Authorization modes

This section only shows the relevant sequence diagram, not the document porter 🐶, for more students, you can see the recommended reading section at the end ~

  1. Authorization code mode

This approach is the most common process and the most secure, and is suitable for Web applications that have a back end. Authorization codes are transmitted through the front end, tokens are stored in the back end, and all communication with the resource server is done in the back end. This separation of the front and back ends prevents token leakage.

  1. Simplify the model

Step 4: There is a risk of hijacking when the access_token is returned directly, so OAuth passes the token in the following way

https://a.com/callback#token=ACCESS_TOKEN

In the URL above, the token argument is the token that the client gets at the front end. Note that the token is fragment, not queryString. This is because OAuth allows URL redirects to HTTP, so there is a risk of “manin the middle attack”. When the browser redirects, the anchor will not be sent to the server. The risk of token leakage is reduced.

This is not a secure way to pass tokens directly to the front end. Therefore, it can only be used in some scenarios with low security requirements, and the validity period of the token must be very short, usually during the session, and the token will be invalid when the browser is closed.

  1. Password mode

Instead of jumping, the token is placed inside the JSON data, and the client gets the token as an HTTP response. This method requires users to provide their own user names and passwords, which is obviously risky. Therefore, this method is only suitable for applications where other authorization methods cannot be adopted and users have high trust.

  1. The client credentials mode

For command line applications without a front end, that is, token requests are made at the command line. The token presented in this way is for the third-party application, not for the user, i.e. multiple users may share the same token.

3.3.4 Types and updates of tokens

Every request to the API must carry a token. To do this, add one to the request header

The Authorization field, where the token is placed.

When the service provider platform issues tokens, two tokens are issued at a time, one for obtaining the access_token of the data and the other for obtaining the new token refresh_token. The expiration time of the access_token is short, and the expiration time of the refresh_token is long. When the access_token expires, refresh_Token is used to request a new Access_token.

Example of an access_token URL request via refresh_token:

https://server.example.com/oauth/token?

grant_type``=refresh_token&

client_id``=CLIENT_ID&

client_secret``=CLIENT_SECRET&

refresh_token``=REFRESH_TOKEN

Parameter Description:

  • Grant_type: refresh_token indicates that the token is required to be updated.
  • Client_id: indicates the id of a client registered with the service provider for identity authentication.
  • Client_secret: the secret key of the authorization server registered with the service provider for identity authentication.
  • Refresh_token: The parameter is the token used to update the token

3.4 CAS compared with OAUTH

  1. designed
  • CAS is specifically designed for centralized authentication, or SSO, and supports login authentication through the OAuth protocol after version 3.5

  • OAuth was created to handle authorization, but SSO was not its original intent. It was only concerned with how to allow third parties to access private resources without requiring users to log in

    • It also defines a complete authentication process, and you can use the specification to implement SSO if you treat user information as a private resource, but it doesn’t have SLO (Single logout) compared to CAS. For example, third-party login of Github and wechat is realized based on OAuth
  1. security
  • CAS

    • Service ticket can be used only once and the shorter the validity period, the better. However, the Access_Token of OAuth has a validity period and can be used multiple times within the validity period
  • The ticket generation needs to be random enough that if the attacker guesses the pattern, the next ticket value can be calculated

  • OAuth

    • The state parameter (placed in query) effectively prevents CSRF attacks
  • For Web applications, the access_token is obtained and used through the back-end interface. Secret is not displayed in the front end, and the possibility of exposure is low
  • For front-end applications, PKCE Extension can effectively prevent authorization code interception attacks
  • A scope mechanism is provided to limit the scope of resources that are acquired
  1. Resources stored
  • CAS: The CAS Client (application system) is the resource storage device, and the user is the resource consumer (application user).
  • OAuth2: The Client (third-party service) is the resource consumption end. Through user authorization, the Client can access user resources (such as personal information and address book) without providing the user’s own account and password.
  • Simply put: a unified account password is required for identity authentication, using CAS; Third party services need to be authorized to use our resources, using OAuth.

4 Implement a simple SSO

The flow chart

For the first time login

Non-first landing

Log out

The module

The module describe
A FE – platform The client A
A BE – platform Server A provides interface services for client A
FE B – platform Client B
B BE – platform Server B provides interface services for client B
FE- Unified login platform SSO login front page
BE- Unified login platform SSO logs in to the Server

interface

The module interface
BE- platform ABE- Platform B Facing the front

• authentication: Queries the login status of the user

• userLogout: A user logs out of the current system

For SSO

• ssoLogout: used for SSO to clear the current system Token

• sendToken: Used to receive tokens from SSO-BE
BE- Unified login platform Facing the front

• the login

• sendToken: Verifies the existence of cookies and requests to send tokens

For the Server

• searchLoginState: : Queries the login status of the current user

• Logout: Used to exit the login state

User platform Interface

interface type Request parameters Returns the parameter Subordinate to the platform
/authentication get Success: status code 200

Failed: Status code: 1001
Platform A, platform B
/userLogout post Platform A, platform B
/ssoLogout post Platform A, platform B

SSO Platform Interface

interface type Request parameters Returns the parameter Subordinate to the platform
/login post account

password
Login successful:

• Status code 200

• token

Login failed:

• Status code 1002
SSO platform
/sendToken post token SSO platform
/searchLoginState get token? : string Login state legal:

• Status code 200

• token

Invalid login state:

• Status code 1001
SSO platform
/logout post token SSO platform

page

The module page
FE- Platform AFE- Platform B The main page

• Indicates that the current system user has logged in successfully

• Exit the login button
FE- Unified login platform The login page

Other implementation schemes

Front and rear end frame

This demo uses Eden Monorepo to organize a total of six sub-projects, including three React front-end sub-projects and three Node back-end projects. The back-end uses gulU framework encapsulated inside the company.

Token persistence

The back-end of Node needs to record the tokens of users who have logged in to the system. Therefore, this Demo uses JSON files to temporarily store the tokens of users who have logged in to the system, and uses FS to read and write the JSON files to simulate the process of storing and deleting the tokens.

Local port

In this demo, only the localhost port is used. The ports are as follows

  • FE- Unified Login platform: 3000
  • FE- Unified Login platform: 4000
  • FE- Platform A: 3001
  • BE- Platform A: 4001
  • FE- Platform B: 3002
  • BE- Platform B: 4002

Front and back end separation cross domain problem

Since it is only a demo project, the proxy in the config file is used to solve the problem temporarily.

devServer: { proxy: { '/api': { target: 'http://localhost:400x', changeOrigin: true, pathRewrite: { '^/api': },},},},Copy the code

5 Discussion

Q: How do I log out of JWT?

A: Since JWT is stateless and the server does not store it, there is no known way to log out that does not involve server storage.

Q: What is the problem when the SSO system is accessed but the service in the maintenance login mode is not implemented?

A: The SSO system is still essentially an “authorization” service, that is, it provides centralized authorization management, but the “authentication” should be implemented by the business itself. For example, the server obtains the user’s authorization information (user_id) through token. If the business side does not maintain the “authorization information (Login state)” (session/JWT), each access needs to go to the SSO server for a complete process. The following two problems will occur: 1. Traffic and requests will be magnified for SSO server; 2. 2. Processes become longer and response times slow for users.

6 Supplementary Content

6.1 Encryption Algorithm

Interested can take a look at this article: on the common seven encryption algorithms and implementation

Encryption algorithms can be divided into symmetric encryption and asymmetric encryption. The encryption key of symmetric encryption algorithm is the same as that of decryption key, while the encryption key of asymmetric encryption algorithm is different from that of decryption key. In addition, there is a kind of hash algorithm that does not need the key. Common symmetric encryption algorithms include DES, 3DES, and AES, common asymmetric algorithms include RSA and DSA, and hash algorithms include SHA-1 and MD5.

Hashing algorithm features:

  • Just as fast: Raw data can be quickly hashed;
  • Reverse difficulty: it is almost impossible to derive the original data from the hash value;
  • Input sensitivity: the hash value of the original data varies greatly as long as there is a small change;
  • Conflict avoidance: It’s hard to find different raw data that get the same hash, the number of atoms in the universe is about 10 to the power of 60 to the power of 80, so 2 to the power of 256 has plenty of room for all the possibilities;

Recommended reading

Cookie, Session, Token, JWT

SSO and CAS knowledge required for the front-end

Analysis of the principle of Oauth.0

Understand the 2.0

OAuth 2.0 in four ways