Hello, everyone. I’m Chen

On Tuesday, I sent the first article of Spring Security series. Some sister left a message saying that she had read a lot of articles, but still did not understand OAuth2.0. This time, Chen spent two days to sort out OAuth2.0 related knowledge, combined with authentication and authorization services + resource services, and once gave everyone to understand!

This is the second article in Spring Security Advancements. The previous article is as follows:

  • Actual combat! Spring Boot Security+JWT Logon authentication!

This article introduces OAuth2.0 related knowledge points, and hand in hand with you to build a certification and authorization center, resource services for OAuth2.0 authorization mode verification, case source code details, a shuttle with you to understand clearly.

The case source project architecture of this article is: Spring Boot + Spring Cloud Alibaba + Spring Security, Spring Cloud Alibaba article directory is as follows:

Why OAuth2.0?

Coding is always about solving problems in production, and to understand why OAuth2 is needed, you need to start with real life.

For example: the owner of the community orders a takeaway, but the access control system of the community does not allow the delivery staff to enter. The only way for the delivery staff to enter the community is for the owner to open the door or tell the password of access control.

Password to inform the delivery staff every time can not enter the community with the password, which obviously caused security risks.

So is there a way to let the delivery guy in without giving away the password?

At this point, I came up with an authorization mechanism, which is divided into the following steps:

  1. A new authorization button is added in the access control system. The delivery boy only needs to click the authorization button to call the corresponding owner
  2. The owner received the little brother’s call and knew that the little brother was asking for authorization, so he made a reply authorization
  3. At this point, the access control system pops up a password (similar to access_token) with a validity period of 30 minutes. Within 30 minutes, the boy can enter the community with this password.
  4. The little brother enters the password to enter the cell

In addition, this authorized password can be used not only through the access control, but also through the access control downstairs, which is very similar to gateways and microservices.

The difference between a token and a password?

In the above example, the token and password have the same function, both can enter the cell, but there are the following differences:

  1. Different timeliness: Generally, there is an expiration time for tokens, such as 30 minutes after expiration, which cannot be modified unless re-authorization is applied. Passwords are usually permanent unless the owner changes them
  2. Different permissions: the permission of the token is limited. For example, in the above example, the younger brother can open the access control of the community and the downstairs where the owner is, but he may not be able to open the access control of other buildings after obtaining the token.
  3. The token can be revoked: the owner can revoke the authorization of the token. Once revoked, the token is invalidated and cannot be used; But passwords are generally not allowed to be revoked.

What is OAuth2?

OAuth is an open standard that allows users to give third-party applications access to their private resources (such as profile pictures, photos, videos, etc.) stored on a website without having to provide a user name and password to third-party applications. This is achieved by providing a token, rather than a username and password, to access the data they store with a particular service provider.

Using tokens allows users to flexibly authorize or revoke permissions on third-party applications.

OAuth2 is the next version of the OAuth protocol, but is not backward compatible with OAuth 1.0.

Traditional Web development login authentication is generally session-based, but there will be a lot of inconvenience to continue using session in the architecture of front and back end separation, because mobile terminals (Android, iOS, wechat small program, etc.) either do not support cookies (wechat small program), or it is very inconvenient to use. These problems can be solved by using OAuth2 authentication.

For everyone, the most common OAuth2 in our Internet applications should be a variety of third-party login, such as QQ authorized login, wechat authorized login, Weibo authorized login, GitHub authorized login and so on.

Four modes of OAuth2.0?

OAuth2.0 protocol supports four different authorization modes:

  1. Authorization code mode: This mode is used for common login functions on third-party platforms.
  2. Simplified mode: In simplified mode, the client server is not required to participate in, directly in the browser to the authorization server for token (token), generally if the site is purely static pages can be used in this way.
  3. Password mode: In password mode, the user directly tells the user name and password to the client, and the client uses this information to apply for a token from the authorization server. This requires a high degree of trust on the client. For example, if the client application and service provider are the same company, you can use this mode to perform front-end and back-end separated login.
  4. Client mode: The client mode means that the client uses its own name instead of the user’s name to apply for authorization from the service provider. Strictly speaking, the client mode is not considered as a solution to the problem OAuth protocol is supposed to solve. However, for developers, It is very convenient to use this mode in some applications that are separated from the front and back or on authentication and authorization servers for mobile devices.

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.

The token acquisition process is as follows:

In the figure above, there are two roles involved: the client, which is responsible for getting tokens, and the certification authority, which is responsible for issuing tokens.

However, not all clients have permission to request the token, so they need to apply in advance at the certification center. For example, not all websites of wechat can be directly accessed, but they need to go to the background of wechat to open the permission.

At least several parameters to be applied to the certification center in advance are as follows:

  1. Client_id: unique ID of a client issued by an authentication center
  2. Client_secret: the secret key of the client, which is equivalent to the password
  3. Scope: indicates the client permission
  4. Redirect_uri: indicates the forward URI used in the authorization code mode. You must inform the authentication authority in advance.

1. Request an authorization code

The client needs to obtain the authorization code from the authentication center. For example, if a third party logs in to use wechat, scanning the login step is to obtain the authorization code from the authentication center of wechat.

The requested URL is as follows:

/oauth/authorize? client_id=&response_type=code&scope=&redirect_uri=Copy the code

The following parameters are carried in the URL above:

  • Client_id: indicates the CLIENT ID assigned by the authentication center. Not all clients can access the authentication center at will
  • Response_type: the fixed value is code, indicating that the authorization code is required to be returned.
  • Scope: indicates the required authorization scope and client permission
  • redirect_uri: Indicates the forward URI. The address to which the authentication authority approves or disapproves the forward. If the authentication authority agrees, it carries one after the URIcode=xxxThis is the authorization code

2. Return the authorization code

After the request in step 1, the authentication authority will ask you to log in and whether to approve authorization. After the user approves authorization, the user directly goes to redirect_URI (this needs to be configured in the authentication authority in advance), and the authorization code will be carried behind this address as follows:

http://xxxx? code=NMoj5y
Copy the code

NMoj5y in the above link is the authorization code.

3. Request tokens

After obtaining the authorization code, the client directly carries the authorization code and sends a request to the authentication center to obtain the token. The requested URL is as follows:

/oauth/token?
 client_id=&
 client_secret=&
 grant_type=authorization_code&
 code=NMoj5y&
 redirect_uri=
Copy the code

The same parameters are the same as above. Different parameters are analyzed as follows:

  • Grant_type: specifies the authorization type. The value of the authorization code is authorization_code
  • Code: This is the authorization code obtained in the previous step

Return the token

After receiving the token request and passing it, the authentication authority returns JSON data containing the token access_token as follows:

{    
  "access_token":"ACCESS_TOKEN"."token_type":"bearer"."expires_in":2592000."refresh_token":"REFRESH_TOKEN"."scope":"read"."uid":100101
}
Copy the code

The access_token is the issued token, while the refresh_token is the refresh token, which is carried to refresh once the token is invalid.

2. Simplified mode

This mode is not commonly used, mainly for those systems without background, directly through the Web jump authorization, the process is as follows:

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. Request tokens

The client requests the token directly with the following URL:

/oauth/authorize?
  response_type=token&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=
Copy the code

This URL is the URL from which the authorization code is obtained in the authorization code mode. Each parameter is parsed as follows:

  • Client_id: indicates the unique Id of a client
  • Response_type: The fixed value of simplified mode is token
  • Scope: indicates the client permission
  • Redirect_uri: the jump URI, which carries the token instead of the authorization code.

Return the token

Redirect_uri: Redirect_URI: redirect_URI: redirect_URI: redirect_URI

https://xxxx#token=NPmdj5
Copy the code

#token=NPmdj5 #token=NPmdj5

3. Password mode

Password mode is also very simple, directly through the username, password to obtain the token, the process is as follows:

1. Request tokens

The authentication center requires the client to enter the user name and password. If the authentication succeeds, a token is issued. The requested URL is as follows:

/oauth/token?
  grant_type=password&
  username=&
  password=&
  client_id=&
  client_secret=
Copy the code

Parameter analysis is as follows:

  • Grant_type: authorization type, password mode Fixed value: password
  • Username: indicates the username
  • Password: password
  • Client_id: indicates the ID of a client
  • Client_secret: indicates the secret key of the client

Return the token

If the preceding authentication succeeds, JSON data is directly returned without skipping, as follows:

{    
  "access_token":"ACCESS_TOKEN"."token_type":"bearer"."expires_in":2592000."refresh_token":"REFRESH_TOKEN"."scope":"read"."uid":100101
}
Copy the code

The access_token is the issued token, while the refresh_token is the refresh token, which is carried to refresh once the token is invalid.

4. Client 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.

The process is as follows:

1. Request tokens

The requested URL is as follows:

/oauth/token?
grant_type=client_credentials&
client_id=&
client_secret=
Copy the code

Parameter analysis is as follows:

  • Grant_type: authorization type. The fixed value is client_credentials in client mode
  • Client_id: indicates the ID of a client
  • Client_secret: indicates the client secret key

Return the token

After successful authentication, the token is returned in the format of JSON data as follows:

{
    "access_token": "ACCESS_TOKEN"."token_type": "bearer"."expires_in": 7200."scope": "all"
}
Copy the code

OAuth2.0 authentication center set up

In order to facilitate the testing of the four authorization modes of OAuth2, a simple authentication center is set up here for the convenience of testing, which will be gradually improved.

1. Case structure

Chen uses Spring Boot + Spring Cloud Alibaba as the foundation to build a new oAuth2-Auth-Server-in-memory module as the authentication center, and the directory is as follows:

The source code of the case has been uploaded to GitHub, concerned public number: code ape technology column, reply keywords 9529 to obtain.

2. Add dependencies

Spring Security and OAuth2 dependencies are as follows:

<! -- Spring Security dependencies -->
<dependency>
   <groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<! --OAuth2 dependencies -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
Copy the code

3. Spring Security Security configuration

This is mainly related to the configuration of Spring Security, there is no clear can Chen’s first article: combat! Spring Boot Security+JWT Logon authentication!

There are four main Settings in the SecurityConfig class, as follows:

1. Encryption method

BCryptPasswordEncoder is used for encryption, as follows:

2. Configure users

In order to facilitate the test, the user information is directly stored in memory, and the code is as follows:

The code above configures two users as follows:

  • User name admin, password 123, role admin
  • User name user, password 123, role user

Inject the AuthenticationManager AuthenticationManager

AuthenticationManager is used in password authorization mode and is injected in advance. If you do not use password mode, you do not need to inject. The code is as follows:

4. Configure a security interception policy

Since the authorization code mode needs to be verified, the form submission mode is enabled and all urls need to be authenticated. The code is as follows:

4. Configure the token storage policy

Tokens can be stored in a variety of ways, such as in-memory, Redis, and JWT, with Redis and JWT being the two most common.

The token will be invalidated once the server restarts.

The code is as follows:

5, OAuth2.0 configuration class

Not all configuration classes can be used as configuration classes for OAuth2.0 authentication authority.

  1. Inheritance AuthorizationServerConfigurerAdapter
  2. Mark @ EnableAuthorizationServer annotation

The code is as follows:

AuthorizationServerConfigurerAdapter need to implement the three methods are as follows:

Here is the detailed configuration of OAuth2 around these three methods.

6. Client configuration

In the introduction of OAuth2.0 protocol introduced, not all clients have the authority to apply for a token to the certification center, first of all, the certification center should know who you are, what qualifications do you have?

Therefore, some necessary configuration is assigned to you by the authentication authority, such as unique client Id, secret keys, permissions.

Client configuration storage also supports a variety of ways, such as memory, database, and the corresponding interface for: org. Springframework. Security. The oauth2. Provider. ClientDetailsService, interface is as follows:

Similarly, for the convenience of testing, it is still loaded in memory, which will be improved later. The complete configuration is as follows:

A few important parameters, as follows:

  • .withClient("myjszl"): Specifies the unique ID of the client as myjszl
  • .secret(): Specifies the secret key, which is encrypted using the encryption algorithm. The secret key is 123
  • .resourceIds("res1"): The resource permission assigned to the client corresponds to the resource service. For example, the micro-service order can be regarded as a resource. As a client, not all resources can be accessed.
  • authorizedGrantTypes(): Defines the authorization types supported by the ca. A total of five authorization types are supported
    • Authorization code mode: authorization_code
    • Password mode: password
    • Client mode: client_credentials
    • Simplified patterns: Implicit
    • Token refresh: refresh_token, which is not in OAuth2’s mode, is defined to indicate that the authentication authority supports token refresh
  • scopes(): Defines the client permissions. This is only an identifier by which the resource service can authenticate.
  • autoApprove: Indicates whether authorization is required. If this parameter is set to false, the user does not need to click “confirm authorization” to return the authorization code
  • redirectUris: Indicates the jump URI

7. Configure the authorization code service

To use the authorization code mode, an authorization code service must be configured to issue and delete the authorization code. Of course, the authorization code can also be stored in various ways, such as memory and database. The code is as follows:

8. Configuration of token service

In addition to the token need to configure the storage strategy, also need to configure the token service AuthorizationServerTokenServices used to create, access, refresh token, the code is as follows:

9. Configuration of token access endpoints

Currently, there are only four configurations, as follows:

  • Configured with the authorization code model needed services, AuthorizationCodeServices
  • The AuthenticationManager required for the password mode is configured
  • Configure the token management services, AuthorizationServerTokenServices
  • configuration/oauth/tokenRequest token URIs allow POST submission only.

The detailed code is as follows:

The Spring Security framework has six default access endpoints:

  • /oauth/authorize: Obtains the endpoint of the authorization code
  • /oauth/token: Gets the token endpoint.
  • /oauth/ confiFIRM_access: user confirms authorization submission endpoint.
  • /oauth/error: authorization service error message endpoint.
  • /oauth/check_token: token resolution endpoint for resource service access.
  • /oauth/token_key: Provides the endpoint of the public key if you use the JWT token.

Of course, if business requirements need to change the default endpoint url, also can modify, AuthorizationServerEndpointsConfigurer have a method, as follows:

public AuthorizationServerEndpointsConfigurer pathMapping(String defaultPath, String customPath)
Copy the code

First parameter: the default endpoint URL that you want to replace

Second parameter: custom endpoint URL

10. Token access security constraint configuration

Configure permissions for endpoints as follows:

OAuth2.0 resource service construction

The purpose of the client to apply for a token is to access the resource, of course, this resource is also divided permissions, a token can not be accessed by all resources.

ResourceIds (“res1”) specifies the resources that can be accessed. Multiple resources can be configured, where res1 is a unique resource.

1. Case structure

Chen uses Spring Boot + Spring Cloud Alibaba as the foundation, and creates an OAuth2-Auth-Th-resource-in-memory module as the authentication center. The directory is as follows:

The source code of the case has been uploaded to GitHub, concerned public number: code ape technology column, reply keywords 9529 to obtain.

2. OAuth2.0 configuration classes

A configuration class that serves as a resource service must meet the following two conditions:

  • Marked with annotations@EnableResourceServer
  • inheritanceResourceServerConfigurerAdapter

The code is as follows:

3. Token verification service configuration

Since the token storage policy used by the authentication authority is in-memory, the server must remotely call the authentication authority’s token endpoint **/oauth/check_token** for verification.

The code is as follows:

Note: There are performance issues with remote validation tokens, but subsequent JWT tokens can be validated locally rather than remotely.

4. Configure the unique ID of the client and the token verification service

The client has a unique identifier, so it needs to be configured as follows:

5. Configure the security mechanism

Scopes (“all”) specify the client’s permissions, and the resource service can intercept urls based on this scope.

The interception methods are as follows:

.access("#oauth2.hasScope('')")
Copy the code

The detailed configuration code is as follows:

Chen has configured the all permission for all paths.

6. Create a test interface

Two new interfaces are created as follows:

  • /hello: Access is available if the authentication is successful
  • /admin: Only withROLE_adminOnly users of the role can access it

Four mode tests of OAuth2.0

The following four services of OAuth2.0 are tested in combination with authentication center and resource service.

Start the certification center and resource service set up above, as shown below:

Authorization code mode

1. Obtain the authorization code

The requested URL is as follows:

http://localhost:2003/auth-server/oauth/authorize? client_id=myjszl&response_type=code&scope=all&redirect_uri=http://www.baidu.com
Copy the code

For browser access, security requires login as follows:

Enter the user name user and password 123 to log in successfully.

The page for confirming authorization is displayed as follows:

Select Apporove, confirm authorization, and successfully jump to Baidu page with authorization code as follows:

Here, 6yV2bF is the obtained authorization code.

2. Obtain the token

http://localhost:2003/auth-server/oauth/token? code=jvMH5U&client_id=myjszl&client_secret=123&redirect_uri=http://www.baidu.com&grant_type=authorization_code
Copy the code

Note: /oauth/token The request mode for obtaining the token must be configured on the authorization server, for example, the POST mode. The code is as follows:

.allowedTokenEndpointRequestMethods(HttpMethod.POST)
Copy the code

The POSTMAN request looks like this:

3. Access resource services

Access the **/hello** interface of the resource service with a token and request as follows:

The request header requires additional Authorization and is in the form of Bearer+” “+access_token.

Note: Bearer must be followed by a blank.

Password mode

The password mode is simple. You can use the user name and password to obtain a token without obtaining the authorization code.

POSTMAN requests the following:

PS: Access the resource yourself and try….. with the obtained token

Simplify the model

The simplified mode is as simple as obtaining the token with the client ID. The requested URL is as follows:

http://localhost:2003/auth-server/oauth/authorize? response_type=token&client_id=myjszl&redirect_uri=http://www.baidu.com&scope=all
Copy the code

This process is the same as obtaining an authorization code. You need to log in and consent to authorization

Finally jump to Baidu, the link directly carries the token, as follows:

In the figure above, 0D5ECF06-B255-4272-b0FA-8e51dDE2ce3e is the obtained token.

PS: Visit the resources and try………. yourself

Client mode

The requested URL is as follows:

http://localhost:2003/auth-server/oauth/token? client_id=myjszl&client_secret=123&grant_type=client_credentials
Copy the code

POSTMAN requests the following:

PS: Visit the resources and try………. yourself

OAuth2.0 tests for other endpoints

Spring Security OAuth2.0 provides other endpoints, so let’s test each one.

1. Refresh the token

OAuth2.0 provides a token refresh mechanism. Once the Access_Token expires, the client can request the authentication authority to renew the token with refresh_Token.

The requested URL is as follows:

http://localhost:2003/auth-server/oauth/token? client_id=myjszl&client_secret=123&grant_type=refresh_token&refresh_token=
Copy the code

POSTMAN requests the following:

2. Verify the token

OAuth2.0 also provides an endpoint to validate the token, requesting the following URL:

http://localhost:2003/auth-server/oauth/check_token? toke=
Copy the code

POSTMAN requests the following:

conclusion

This paper introduces the principle of OAuth2.0 protocol and four authorization modes, and sets up the authentication and authorization center and carries on the test of the four modes.

This is very detailed as an OAuth2.0 primer………..