preface

Single sign-on (SSO) is widely used in the current system architecture. It unlocks the authentication system of multiple subsystems to realize multiple uses of one entry. However, some small problems will be encountered in the single sign-on architecture.

Session sharing

Session sharing is the most direct and easiest way to implement single sign-on. The user authentication information stored in the Session, that is, with the value stored in the Session for user credentials, which used within a single site is normal and easy to implement, and the user authentication, user information management and the separation of business application scenarios that will meet the problem of single sign-on, simple in application system, subsystem of a few cases, Consider using Session sharing to handle this problem.



For this architecture, I use the Session sharing scheme based on Redis. The Session is stored on Redis, and the global Cookie Domain of the entire system is set on the top-level Domain so that the SessionID can be shared among subsystems. Distributed Session sharing solution, this article is recommended.

This scheme, there are serious scalability problems first, ASP.NET Session storage must be SessionStateItemCollection objects, and storage structure is encrypted storage after serialization.

And when the user access to applications, he first do is remove all the content is in storage containers, and deserialization as SessionStateItemCollection object.

This determines that he has the following constraints:

1. The types involved in a Session must be owned jointly by subsystems (that is, assemblies and types must be consistent), which results in many restrictions on the use of sessions;

2. The case of cross top-level domain is completely unmanageable;



Second, openID-based single sign-on

When the user logs in to a subsystem, the OpenId is sent to the server. The server constructs the user authentication information according to the OpenId, which is mostly used in the system combining C/S and B/S. The process is as follows:

As can be seen from the figure above, this set of single sign-on relies on the transmission of OpenId, and its verification is based on the storage and transmission of OpenId.

1. When a user logs in for the first time, the user name and password are sent to the authentication service.

2. The authentication service returns the user id OpenId to the client.

3. Storage is performed on the client.

4. When accessing the subsystem, send OpenId to the subsystem;

5. The subsystem forwards OpenId to the authentication service;

6. The authentication service returns user authentication information to the subsystem.

7. The subsystem constructs user authentication information and returns the authorized content to the client.

The main problem of this single sign-on authentication mechanism is that it stores the user’s OpenId in the client based on C/S architecture and sends OpenId between subsystems, while it is difficult to do so in B/S mode. To deal with this problem, we will introduce the next approach, which will solve the storage and transfer problems of OpenId in B/S mode.



Third, Cookie-based OpenId storage scheme

As we know, the function of Cookie is to act as an information carrier to transfer information between the Server and Browser. Cookies are generally separated by domain names. For example, cookies of A.xxx.com and B.xxx.com cannot access each other. But the subdomain can access the cookies of the parent domain. That is, A.xxx.com and B.xxx.com can access the cookies under XXx.com, so the cookies of top-level domain names can be used as the carrier of OpenId.

The validation steps are very similar to the second method above:

1. Log in to a site that provides authentication services;

2. Write OpenId into top-level domain Cookie;

3. Access subsystem (Cookie with OpenId)

4. The subsystem takes out the OpenId and sends the OpenId to the verification service

5. Return the user authentication information

6. Return the content after authorization

In the above two methods, we can see that problems such as types in Session sharing scheme are decoupled through OpenId, and the construction of user authentication information is more flexible, and the authentication between subsystems is independent of each other. However, in the third scheme, we assume that all subsystems are the same top-level domain name. In a real production environment where multiple domain names are common, you have to consider how to solve the cross-domain problem.



Single sign-on processing in B/S multi-domain environment

In the case of multiple top-level domains, we will not be able to share openids across subsystems. When dealing with cross-domain problems in B/S environment, we should think of JSONP solution first.

The verification steps are as follows:

1. Users log in through the login subsystem;

2. User login subsystem records user login status, OpenId and other information;

3. Users use business subsystem;

4. If the user does not log in to the service subsystem, the user is redirected to the user login subsystem.

5. The user subsystem transmits the user OpenId to the business subsystem through JSONP interface;

6. Business subsystem invokes validation service through OpenId;

7. The authentication service returns authentication information, and the business subsystem constructs user login credentials; (At this point, the user client has been matched with the authentication information of the sub-service system.)

8. Return the user login result to the user login subsystem. If the user successfully logs in, the user is redirected to the service subsystem.

9. Return the authorized content to the client;

Fifth, security issues

After the above steps, the problem of single sign-on in the case of cross domain can be solved. At the beginning of the whole development process, we used the user table to record an OpenId field to save the user OpenId, but this mechanism obviously had some security and scalability problems. This scalability problem is mainly reflected in one aspect: the contradiction between OpenId’s security and user experience.

The entire single sign-on mechanism determines that OpenId will appear on the client, so OpenId needs to have an expiration mechanism. If users log in from one terminal, they can choose to refresh OpenId every time they log in or exit, while there will be conflicts in the case of multi-terminal login: When one terminal refreshes OpenId, other terminals cannot properly authorize.

In the end, I went with a single-user multi-OpenID solution. Every time a user logs in with a user name/password, an OpenId is generated and stored in Redis, and the expiration time is set. In this way, multiple Openids will be corresponding to multiple terminal logins, so that no one OpenId will be invalid and all terminal authentication will be invalid.

The last

Welcome to pay attention to my public number [programmer chasing wind], the article will be updated in it, sorting out the data will be placed in it.