I. Implementation mechanism

When the user accesses application system 1 for the first time, because he has not logged in, he will be guided to the authentication system for login. Based on the login information provided by the user, the authentication system verifies the identity. If the authentication succeeds, the system returns a ticket to the user. When the user accesses another application, he or she will bring the ticket with him or her as the authentication credential. After receiving the request, the application system will send the ticket to the authentication system to check the validity of the ticket. If the verification succeeds, the user can access application system 2 and Application system 3 without logging in again.

Benefits of using SSO

  • Users can log in to the application system for multiple times. Users no longer need to enter a user name and password each time, nor do they need to remember multiple sets of user names and passwords. Single sign-on platforms can improve the user experience with the application system.
  • Convenience For the administrator The system administrator only needs to maintain a unified set of user accounts, which is convenient and simple. In contrast, system administrators used to have to manage multiple sets of user accounts. Each application system has a set of user accounts, which not only brings inconvenience to the management, but also is prone to management loopholes.
  • Simplified application system development When developing a new application system, the user authentication service of the single sign-on platform can be directly used to simplify the development process. Single sign-on (SSO) Platform Implements sso by providing a unified authentication platform. Therefore, the application system does not need to develop a user authentication program.

Third, SSO implementation scheme

Common cross-domain login problems

1. Log in to the same root domain

If our site has more than one business, then they may be deployed on different machines and often need different domain names to distinguish them. However, all businesses depend on a set of account system, so we need to solve the login problem of all sites through one login, so we can use the most stupid method at this time: That is, a successful login, the Cookie is written to the root domain, so that all sites can achieve, the same root domain Cookie sharing, the natural implementation of “single sign-on”.

2. For login problems in multiple root domains

If there are multiple root domains, then the above mechanism will not be able to achieve “single sign-on” in this case. Because the above can achieve the “single sign-on” effect. Because of the browser and Http protocol support. However, Cookie sharing between sites across the root domain is more complex.

  • Method 1: After a successful login, write cookies back to multiple domain names.

This can be very simple, you can write with response on the back end, or with front-end JS, but it must be written individually for all sites that require “single sign-on”. This approach doesn’t work with your feet either, because you need to maintain a list of sites, which is complicated to maintain and especially painful to add to. The destruction of cookies is also very complex, because it is still necessary to delete all the cookies under the domain name. So you increase the amount of work that you had to do by a factor of n. This is desirable for small sites.

  • Method 2: json

Those of you who have worked on the front end probably know that you can use JSONP to make cross-domain requests, and we are solving the problem of unified login in multiple domains, which seems to make sense. But is the login done on the Server side? We’re doing cross-domain processing on the Client side, which doesn’t make sense in any way. At the same time, this method needs a lot of maintenance costs, each request to go to the fixed domain to take the corresponding Cookie after the request. Think maintenance headaches.

  • Method 3: Introduce an intermediate Server

This approach is a simplified version of SSO, and the implementation idea is very “cunning”. But for small websites to do cross-domain login processing is very useful, the specific ideas are as follows:

First, we have two domains to implement single sign-on, and we need an intermediate Server.

  1. We have a system domain name of xulingbo.net. When we login, we visit xulingbo.net/wp-login to login. After successful login, the Cookie will be written back to the xulingbo domain name.

  2. We also have a system domain name javaWeb.com. When we visit insip-JavaWeb, we have no Cookie, so the request jumps to the intermediate system jump. In this case, you need to bring the current domain name to the parameter for jump verification. The jump system is in the Xulingbo domain: jump.xulingbo.net. And then you get the Cookie that was written in the Xulingbo domain.

  3. Jump requests jump.inside-javaWeb.net at the redirect site. Jump requests jump.inside-javaWeb.net at the redirect site. After the request, the Jump system writes the Cookie back to the insip-Java Web domain name, thus achieving simple single sign-on. As shown in the figure below:

However, this method is not very flexible, and the security of data transmission is not guaranteed. In addition, there is nothing to do when destroying cookies, and only the destruction of all traversal.

  • Method 4: CAS-based SSO system

Central Authentication Service (CAS) is a good single sign-on framework for Web applications, including Java,.NET, PHP, Prel, Apache, uPortal, Ruby, etc. The implementation mechanism is not complex but the idea is clever. Single sign-on can also be implemented quickly with CAS. The following figure illustrates the sso login and authentication process for a single domain:

The CAS consists of the CAS Client and the CAS Server. The Client is embedded in the interceptor or filter that requires SSO login.

  1. First the browser makes a request to site 1.
  2. Site 1 finds that the current request does not have a valid Cookie and redirects to the CAS Server, i.e. SSO Server.
  3. The CAS Server login page is displayed, requiring users to log in.
  4. After login, the user writes the CAS Server Cookie to the browser, generates a ticket, and uses a 302 to jump to the CASClient. This ensures that the user is unaware.
  5. The CAS Client sends the generated ticket to the CAS Server for authentication. After the authentication succeeds, site 1 generates its own Cookie and writes it back to the user’s browser. Then, the login succeeds.

In this way, you can ensure that the current browser has the Cookie of site 1 under the domain name of site 1, and the current browser also has the Cookie of CAS Server. Next look at the login to site 2:

Note: 1, CAS Server’s Cookie hijacking problem, if the CAS Server’s Cookie is hijacked, then it is equivalent to get everything, so you must use HTTPS to achieve this process. 2. If a ticket is used, a ticket can be used only once and becomes invalid immediately after one check. At the same time, it needs to be timeliness, generally 5 minutes. Finally, the ticket generation rule should be random and cannot be knocked out. 3. Each system can also rely on SSO for its own Session, so as to ensure the consistency of all Session rules and facilitate centralized control.

Note: The operation system is also handled in this way. Based on the current situation, the single sign-on system can be handled as follows

  • Disadvantages of using Soa services to realize login and logout: you have to determine whether the user is logged in and whether the session is expired. Lack of permission control, have to achieve their own advantages: simple implementation
  • The security of the login function in web service is low
  • Use Spring Security + Oauth2 to implement login and login advantages: Enterprise-level, high Security Multiple Security authentication methods are provided to handle complex permission control

Introduction to Spring Security

  • What is Spring Security?

Spring security is a powerful and highly customizable authentication and access control framework that provides javaEE based enterprises with comprehensive security services for their software. It is the de facto standard for protecting Spring-based applications. The primary functions are “authentication” and “authorization” (or access control). At the authentication layer, Spring Security supports multiple authentication modes.

  • Core functions 1, authentication (who you are) 2, authorization (what you can do) 3, attack protection (prevent forged identity)
  • What is Spring Security authentication?
  1. Prompt the user to enter the user name and password for login.
  2. The system (successfully) verifies that the password for the user name is correct.
  3. Get information about the user’s environment (their list of roles, etc.)
  4. Create a secure environment for your users.
  5. The user performs, and may perform, some operations that are potentially protected by access control mechanisms that check the required permissions on the current secure environment information for the operation.

Verification Process

  1. User name and password are combined into one instance UsernamePasswordAuthenticationToken (an instance of the Authentication interface, we’ve seen before).
  2. The token is passed to the AuthenticationManager instance for authentication.
  3. The AuthenticationManager fully populates the Authentication instance and returns successful Authentication.
  4. Security environment is by calling SecurityContextHolder. GetContext (). SetAuthentication (…). Which is passed to the returned validation object established.

Five, the OAUTH2

  • Noun definition
  1. A Third party application is an application that can be used as a client.
  2. HTTP service: HTTP service provider, hereinafter referred to as “service Provider”
  3. Resource Owner: The Owner of the Resource.
  4. User Agent: The User Agent, usually the browser.
  5. Authorization Server: Indicates the server used by the service provider to process authentication.
  6. Resource server: Indicates the server on which the service provider stores user-generated resources. It can be the same server as the authentication server or different servers.
  • The thinking of request

OAuth sets an authorization layer between the “client” and the “service provider.” Clients “cannot directly log in to the” service provider “, but only to the authorization layer, to distinguish the user from the client.” The token used by the client to log in to the authorization layer is different from the user’s password. The user can specify the scope and validity period of the authorization token at the time of login. After the Client has logged into the authorization layer, the Service Provider will open the User’s stored data to the Client based on the scope and validity period of the token.

  • Run the process

(A) After the user opens the client, the client requests authorization from the user. (B) The user agrees to authorize the client. (C) The client uses the authorization obtained in the previous step to request a token from the authentication server. (D) After the authentication server authenticates the client, it confirms the information and agrees to issue the token. (E) The client uses the token to apply for resources from the resource server. (F) The resource server confirms that the token is correct and agrees to open the resource to the client. It is not hard to see that of the six steps above, B is the key, that is, how the user can authorize the client. With this authorization, the client can obtain the token and, in turn, the resource from the token.

Combined with the above figure, protecting your application with Oauth2 can be broken down into three simple steps

  1. Configure the resource server Authorization Service.
  2. The authentication server Resource Service is configured.
  3. Configure spring security

All token requests will be processed in the Spring MVC Controller EndPoints, and the process of accessing the protected resource service will be placed in the standard Spring Security request filters. -authorizationEndpoint: The default URL is/oAuth /authorize. -tokenEndpoint: The default URL is/oAuth /authorize. The default URL is/oAuth/Token.

  • Authorization mode of the client

A client must obtain authorization grants from users to obtain access tokens. OAuth 2.0 defines four types of authorization.

  1. Authorization Code Mode
  2. Implicit mode
  3. Password Mode (Resource Owner Password Credentials)
  4. Client Credentials Mode

Authorization Mode Explanation

  • Authorization code mode

The authorization code mode has the most complete functions and the most rigorous procedures. Its characteristic is to interact with the authentication server of the “service provider” through the back-end server of the client.

It takes the following steps: (A) The user accesses the client, which directs the user to the authentication server. (B) The user selects whether to grant authorization to the client. (C) Assuming the user is authorized, the authentication server directs the user to the “redirection URI” specified by the client, along with an authorization code. (D) The client receives the authorization code, attaches the previous “redirect URI”, and requests the token from the authentication server. This step is done on a server in the back of the client and is not visible to the user. (E) The authentication server checks the authorization code and the redirection URI, and sends the Access token and refresh token to the client after confirming that they are correct.

Here are the parameters required for the steps above. In step A, the URI for the client to apply for authentication contains the following parameters:

  • –response_type: indicates the authorization type, which is mandatory and has a fixed value of “code”.
  • –client_id: client ID. This parameter is mandatory
  • — redirect_URI: indicates the redirection URI. This option is optional
  • –scope: Specifies the scope of the permission to apply for. This parameter is optional
  • –state: indicates the current state of the client. You can specify any value. The authentication server returns this value unchanged.
demo: GET /authorize? The payload = code&client _id = s6BhdRkqt3 & state = xyz & redirect_uri = HTTPS % 3 a % 2 f % 2 fclient % 2 eexample % 2 ecom % 2 FCB HTTP / 1.1 Host:  server.example.comCopy the code

In step C, the server responds to the URI of the client with the following parameters: –code: indicates the authorization code. This parameter is mandatory. The validity period of the code should be very short, usually set to 10 minutes. The client can only use the code once, otherwise the authorization server will reject it. This code is in one-to-one correspondence with the client ID and the redirection URI. –state: If the request from the client contains this parameter, the response from the authentication server must also contain this parameter.

HTTP / 1.1 302 Found the Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA & state = xyzCopy the code

In step D, the client requests an HTTP request for the token from the authentication server, which contains the following parameters:

  • –grant_type: indicates the authorization mode. This parameter is mandatory. The value here is “authorization_code”.
  • –code: Indicates the authorization code obtained in the previous step. This parameter is mandatory.
  • — redirect_URI: indicates the redirection URI. This parameter is mandatory and must be the same as the value of this parameter in step A.
  • –client_id: client ID. This parameter is mandatory.

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

  • –access_token: indicates the access token. This option is mandatory.
  • –token_type: Indicates the token type. This value is case insensitive and mandatory. It can bea bearer type or MAC type.
  • — expiRES_in: indicates the expiration time, in seconds. If this parameter is omitted, you must set the expiration time in another way.
  • –refresh_token: Refresh_token is used to obtain the next access token. This option is optional.
  • –scope: indicates the permission scope. If the scope is the same as that applied by the client, this parameter can be omitted.

The common third party login also uses this method, first request the code, and then through the code to obtain the token.

  • Implicit Grant Type is a mode where users ask for tokens directly from a browser without using a third-party server, skipping the “authorization code” step. All steps are done in the browser, the token is visible to the visitor, and the client does not need to authenticate.

It takes the following steps: (A) The client directs the user to the authentication server. (B) The user decides whether to grant authorization to the client. (C) Assuming the user is authorized, the authentication server directs the user to the “redirect URI” specified by the client and includes the access token in the Hash section of the URI. (D) The browser makes a request to the resource server, which does not include the Hash value received in the previous step. (E) The resource server returns a web page containing code that can retrieve the token in the Hash value. (F) The browser executes the script obtained in the previous step and extracts the token. (G) The browser issues the token to the client.

Here are the parameters required for the steps above. In step A, the HTTP request sent by the client contains the following parameters:

  • -response_type: Indicates the authorization type. The value is “token” and is mandatory.
  • -client_id: specifies the ID of a client. This parameter is mandatory.
  • – redirect_URI: indicates the REdirection URI. This parameter is optional.
  • -scope: indicates the permission scope. This parameter is optional.
  • -state: indicates the current state of the client. You can specify any value. The authentication server returns the value unchanged.

Here’s an example:

GET /authorize? The payload = token&client _id = s6BhdRkqt3 & state = xyz & redirect_uri = HTTPS % 3 a % 2 f % 2 fclient % 2 eexample % 2 ecom % 2 FCB HTTP / 1.1 Host: server.example.comCopy the code

In step C, the authentication server responds to the URI of the client with the following parameters:

  • -access_token: indicates the access token. This parameter is mandatory.
  • -token_type: indicates the token type. This value is case-insensitive and mandatory.
  • -expires_in: indicates the expiration time, in seconds. If this parameter is omitted, you must set the expiration time in another way.
  • -scope: indicates the permission scope. If the scope is the same as that applied by the client, this parameter can be omitted.
  • -state: If the request from the client contains this parameter, the response from the authentication server must also contain this parameter.

Here’s an example:

HTTP/1.1 302 Found
     Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
               &state=xyz&token_type=example&expires_in=3600
Copy the code
  • Password mode

In the Resource Owner Password Credentials Grant mode, users provide their user name and Password to clients. The client uses this information to ask the “service provider” for authorization. In this mode, the user must give his password to the client, but the client must not store the password. This is usually used when the user has a high level of trust in the client, such as if the client is part of the operating system or is produced by a well-known company. The authentication server can only consider using this mode when other authorization modes cannot be implemented.

It takes the following steps: (A) The user provides A user name and password to the client. (B) The client sends the user name and password to the authentication server and requests the token from the latter. (C) After the authentication server confirms the error, it provides the access token to the client.

B In step B, the HTTP request sent by the client contains the following parameters: -grant_type: indicates the authorization type. The value here is password. This parameter is mandatory. -username: indicates the username. This parameter is mandatory. -password: indicates the user password. This parameter is mandatory. -scope: indicates the permission scope. This parameter is optional.

Here’s an example:

POST/token HTTP / 1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW content-type: application/x-www-form-urlencoded grant_type=password&username=johndoe&password=A3ddj3wCopy the code

In step C, the authentication server sends an access token to the client. Here is an example.

HTTP/1.1 200 OK Content-type: application/json; charset=UTF-8 Cache-Control: no-store Pragma: no-cache {"access_token":"2YotnFZFEjr1zCsicMWpAA"."token_type":"example"."expires_in": 3600,"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"."example_parameter":"example_value"
     }
Copy the code

For other authentication information, refer to the following address.

  • Client Credentials Grant In Client Credentials Grant mode, a Client authenticates to a “service provider” in its own name, rather than in the name of a user. Strictly speaking, the client pattern is not part of the problem that the OAuth framework is intended to solve. In this mode, the user registers directly with the client, and the client requests the “service provider” to provide services in its own name. In fact, there is no authorization problem.

It takes the following steps: (A) The client authenticates itself to the authentication server and asks for an access token. (B) After the authentication server confirms the information, it provides the access token to the client.

In step A, the HTTP request sent by the client contains the following parameters: -grantType: indicates the authorization type. The value here is clientCredentials. This parameter is mandatory. -scope: indicates the permission scope. This parameter is optional.

POST/token HTTP / 1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW content-type: application/x-www-form-urlencoded grant_type=client_credentialsCopy the code

The authentication server must somehow authenticate the client. In step B, the authentication server sends an access token to the client. Here is an example.

HTTP/1.1 200 OK Content-type: application/json; charset=UTF-8 Cache-Control: no-store Pragma: no-cache {"access_token":"2YotnFZFEjr1zCsicMWpAA"."token_type":"example"."expires_in": 3600,"example_parameter":"example_value"
     }
Copy the code

Attached I wrote a spring-security+oauth2 project, can refer to use, anyway, MY own project using this. Github.com/jiezaizone/… Another single sign-on method is the Keycloak single sign-on

About me

Continuous output of original articles, this is Liu Rongjie’s first original article