The project introduced in this paper is an application based on OATH2 protocol, and its functional logic is similar to QQ Interconnection and Weibo open platform, both of which are the same set of authentication and authorization process.

The project structure is simple and easy to understand, but it does not cut corners. After learning the content of this article, readers can directly obtain the project code in the article for study or copy it to the company’s production project for modification and use, so as to truly achieve the purpose of learning for practical use.

Technology Stacks involved:

  • java
  • Springboot 2.0.1. RELEASE
  • Spring security 2.0.1. RELEASE
  • Spring cloud oauth2 2.0.0. M7
  • Mybatis 2.0.1

This project includes features as follows

  • A new user
  1. User registration automatically assigns role rights
  2. A user can access only the role permission access path that he/she has
  • Open platform
  1. Users can apply for obtaining customer ids and customer keys
  2. You can obtain the authorization code by customer ID
  3. Users can obtain access token and ReferrSH token and Scope by customer ID and key and authorization code
  • Resource API service (order-service/open-api-service)
  1. You can customize the authorized URL
  2. You can customize the scope of restricted URL access
  3. If the user is not authorized or has insufficient access permission, a message is displayed
  4. Users access the corresponding URL using the Access token

An overview of the project

First, take a look at the structure diagram of the project to understand the general layout of the project

  • . Idea: file generated by idea
  • Docker: Stores the Dockerfile used to build container images
  • Config: Configuration for Spring Security and Web in the project
  • Controller: requests the controller
  • Entity: object entity class package
  • Handler: logic processing class package
  • Mapper: Stores the Mybatis Mapper interface class
  • Service: Business logic processing class
  • Util: Generic utility class
  • Postman: test case of the Postman tool
  • SQL: Initializing SQL statements for the project
  • Templates: page template file

Next, the details of the project will be formally introduced. Since the project itself has many Chinese annotations, the specific implementation of some code will be contracted when explaining. If readers are not used to it, they can click online comparison here or fork into their own project to read the project code

How is the user authenticated by interception

  1. Since the nominal SecurityConfig inherited WebSecurityConfigurerAdapter, explain SecurityConfig security configuration will be a Http adapter
  2. through@EnableWebSecurityThis class takes effect if the HttpSecurity security configuration is turned on

  1. Rewrite WebSecurityConfigurerAdapter configure (HttpSecurity HTTP) method
  2. Specify where request URLS are allowed without interception
  3. Specifies which requests need to be intercepted for validation

  1. Rewrite WebSecurityConfigurerAdapter configure (AuthenticationManagerBuilder auth) method
  2. Specify the service class to handle authentication as MyUserDetailsService
  3. Check whether the entered password is consistent with the user password in the database

  1. The custom class MyUserDetailsService implements the UserDetailsService interface of Spring Security
  2. Overrides the loadUserByUsername(String username) method, where username is the property and value passed by the page, the property is fixed
  3. Get the permission details for the user permission table and set the contents to the Userdetails.authorities property
  4. Return User, the subclass of UserDetails

User registration automatically assigns role rights

User registration inserts data into the user table and a copy of data into the user role table. Of course, it can also be designed more complex, such as according to the source, time, whitelist, internal recommendation set different permissions, readers can expand.

A user can access only the role permission access path that he/she has

  1. Retrieve all permissions of the current user
  2. Take the permission identity field for the permission and wrap it into a List collection
  3. Save the wrapped permission List collection into the UserDetails object

  1. Fetch the contents of all permission tables
  2. Http.authorizerequests () Gets the current authentication object
  3. Set all the contents of the permission table into authorizeRequests. AntMatchers represent blocked urls and hasAnyAuthority represents accessible permission identifiers
  4. In the figure above, the user can access the blocked URL because the user has set the permission identifier for the permissions they own

Users can apply for obtaining customer ids and customer keys

Let’s look at the table structure first. Oauth_client_details is the table that comes with Spring Cloud Oath2, and user_client_secret is the table that we created ourselves

  1. Generate OauthClientDetails data and save it to the database
  2. Get the current logon information and bind the clientId of OauthClientDetails to the user_Client_secret table

You can obtain the authorization code by customer ID

The implementation is in the Spring-Security-Oauth package and is not self-implemented in this project

Customer ID get authorization code request url: http://localhost:8080/oauth/authorize? response_type=code&client_id=client_92&redirect_uri=http://localhost:8080/code

  1. Response_type =code is fixed because we are getting the authorization code
  2. ID of the customer applied by the customer
  3. Web_server_redirect_uri in the oAUTH_client_DETAILS table

Obtain the access_token with the authorization code

Specific implementation in spring ws-security – request packet of org. Springframework. Security. Oauth2. The provider. The endpoint. TokenEndpoint class, students are interested in can be debug debugging in it

With the authorization code for access_token request url: http://localhost:8080/oauth/token? grant_type=authorization_code&code=8fGtOV&client_id=client_92&client_secret=123456&redirect_uri=http://localhost:8080/co de&scope=all

  1. The authorization code obtained by the customer ID
  2. ID of the customer applied by the customer
  3. Customer ID corresponding to the customer key applied for by the customer
  4. Web_server_redirect_uri in the oAUTH_client_DETAILS table
  5. Scope in oAUTH_client_details table
If an error similar to the following occurs, the code is invalid. You can obtain the authorization code again
{
    "error": "invalid_grant"."error_description": "Invalid authorization code: iq30f9"
}
Copy the code

Merchant ID and merchant secret key get accessToken and refresh accessToken

  • Grant_type: authorization type, set to password mode
  • Username: username
  • Password: indicates the user password
  • Client_id: indicates the obtained client Id
  • Client_secret: obtained client secret key
  • Scope: Scope identifier, taken from scope in the oAUTH_client_details table

Refresh the accessToken

Refresh the accessToken request url: http://localhost:8080/oauth/token? grant_type=refresh_token&refresh_token=4741d043-e202-4de0-ae21-4f5c7ec5626e&client_id=client_1&client_secret=123456

Verify accessToken is valid

Verify accessToken request url: http://localhost:8080/oauth/check_token? token=1131809b-ee12-4aea-9823-ea4454b96f2d

Resource API service

At this point, let’s look at another project, order-service, which would be better called order-api-resource, but I’m not going to change it. The structure and code in this project are sparse, so it’s easier to learn.

How can I customize the URL for blocking authorization

antMatchers()
authenticated()
/api/trade/

How to customize the scope of limited URL access

access()

If the user is not authorized or has insufficient access permission, the corresponding information is displayed

How can users access corresponding URLS through access Tokens

  1. Configure the service address that validates accessToken, which is the service from which accessToken is issued
  2. Need to configure the merchant ID and merchant secret key to obtain accessToken, used to pass the verification of the development platform. AccessToken is valid, but there is no need to authenticate login. Why? Let’s look at the source code:

Remotetokenservices.java in spring-security-oAuth2-2.2.1.release -sources.jar is used to remotely invoke the Token service (development platform) for operation

  1. Because the Authorization attribute is set for the HTTP header to indicate the need for authentication, clientId and clientSecret in the above configuration are taken, otherwise the sending request will fail to be authenticated by the open platform
  2. PostForMap () wraps the parameters and performs request sending

Project code point here

The problem

/oauth/check_token 401