preface

In the long development process, permission authentication is an eternal topic, with the development of technology, from the previous sessionID-based mode to the present token mode. Sessions were often used for singleton applications, but later distributed applications became a big part of it due to the rise of microservices. This article introduces session-based single application authentication. The token-based authentication will be introduced later.

What is certification

The process of entering an account and password to log in is authentication to see if it is valid. Authentication is to protect the system’s private data and resources. Users can access the system resources only when their identities are valid. User authentication is the process of judging whether a user’s identity is legitimate. Common user authentication methods include password login, SMS login, and fingerprint authentication.

What is a conversation

After a user is authenticated, the user information can be saved in a session to prevent the user from being authenticated every time. A session is a mechanism to maintain the login status of the current user. Common modes are session-based and token-based.

Session Mode Session

After a user is successfully authenticated, the user data generated on the server is stored in the session, and the session_ID sent to the client is stored in the cookie. Session_id can be used to verify whether the server has session data when the user client requests, so as to complete the legitimate verification of the user. The client session_ID becomes invalid when the user logs out of the system or the session expires.

Token Session

After the user is authenticated, the server generates a token and sends it to the client. The client stores the token in the cookie or localstorage. Each request carries a token. After receiving the token, the server can verify the user’s identity.

conclusion

Session-based authentication is customized by the Servlet specification. To store session information on the server, memory resources need to be occupied, and the client needs to support cookies. The token-based mode does not require the server to store tokens and does not limit the storage mode of the client. Nowadays, there are many clients in the Internet era, so token is more appropriate.

What is authorization

For example, wechat, the function of sending red packets, the function of sending moments are wechat resources, users can only use the function of sending red packets normally, for example, users do not bind bank cards at the beginning, users do not have the right to send red packets. Authentication is to protect the validity of user identities, while authorization is to divide private data in a more fine-grained manner. Authorization occurs after authentication and controls the access of different users to different resources. Authorization is the process of user authentication to control user access to resources based on user permissions. If a user has access permission to a resource, the user can access the resource normally. If the user does not have access permission, the user is denied access.

Data model for authorization

Authorization can be simply understood as Who performs How operations on What(which), including the following: Who, or Subject, generally refers to users or programs that need to access resources in the system. What refers to resources, such as system menu, page, button, code method, system commodity information, system order information, etc. System menus, pages, buttons and code methods all belong to system functional resources. For the Web system, each functional resource usually corresponds to a URL. System commodity information and system order information are entity resources (data resources). Entity resources consist of resource types and resource instances. For example, commodity information is resource type, and commodity numbered 001 is resource instance. How, Permission, defines the user’s Permission to operate resources. Permission is meaningless without resources, such as the user’s Permission to query, add, call a code method, and modify Permission of the user numbered 001, etc. By Permission, users can know what operation Permission they have on resources. The relationship among subjects, resources, and permissions is as follows:

The data model related to principals, resources, and permissions is as follows: principals (user ID, account, password,…) Resources (resource ID, resource name, access address,…) Permission (Permission ID, Permission ID, Permission Name, resource ID,…) Role (Role ID, role name,…) Role and permission relationship (Role ID, permission ID,…) Principal (user) and role relationships (user ID, role ID,…) The relationship among subjects (users), resources and permissions is as follows:

Generally, enterprise development combines the resource and permission tables into one permission table, as follows: Resource (resource ID, resource name, access address,…) Permission (Permission ID, Permission ID, Permission Name, resource ID,…) Combined with permission (permission ID, permission ID, Permission Name, resource name, resource access address,…) The relationship between the modified data models is shown as follows:

RBAC

Role-based access control

RBAC role-based Access Control implements role-based authorization. For example, the Role of the principal is the general manager. The Access Control flow is as follows:

According to the judgment logic in the figure above, the authorization code can be expressed as follows:

In the preceding figure, if the roles required for salary query are changed to General manager and department manager, you need to change the judgment logic to Check whether the user’s role is general manager or department manager, and modify the code as follows:

According to the above example, when the permission of the role needs to be modified, the authorization related code needs to be modified, and the system has poor scalability.

Resource-based access control

The RBAC resource-based Access Control implements authorization by Resource or permission. For example, users can query employee salary information only when they have the permission to query salary information. The Access Control flow is as follows:

Judging from the above figure, the authorization code can be expressed as:

Advantages: When designing the system, the permission identification for salary query is defined. Even if the roles required for salary query are changed to general manager and department manager, there is no need to modify the authorization code, and the system has strong scalability.

Session-based authentication

Session-based authentication process: After successful user authentication, the user data generated on the server is stored in the Session (current Session), and the sesssion_id sent to the client is stored in the cookie. In this way, the session_id can be used to verify whether there is session data on the server when the client requests, so as to complete the legitimate verification of the user. The client session_ID becomes invalid when the user logs out of the system or the session expires. The following is the flow chart of session authentication:

The session-based authentication mechanism is customized by the Servlet specification. The Servlet container has been implemented and users can implement the HttpSession operation method. The following is the HTTPSession-related operation API.

Session-based projects

This case project uses maven to build, using SpringMVC, Servlet3.0 implementation.

Creating a Maven project

Create maven project security-session and install the following dependencies: (1) Install the package as war; (2) install tomcat7-maven-plugin as war

<? xml version="1.0" encoding="UTF 8 ‐"? > <project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="Http://www.w3.org/2001/XMLSchema ‐ instance" 
xsi:schemaLocation="Http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven ‐ 4.0.0. XSD"> < modelVersion > 4.0.0 < / modelVersion > < groupId > com. The jichi. Security < / groupId > < artifactId > security ‐ session < / artifactId > < version > 1.0 ‐ SNAPSHOT < / version > < packaging > war < / packaging > < properties > < project. Build. SourceEncoding > UTF 8 ‐ < / project. Build. SourceEncoding > < maven.com piler. Source > 1.8 < / maven.com piler source > < maven.com piler target > 1.8 < / maven.com piler. Target > < / properties > < dependencies > < the dependency > < the groupId > org. Springframework < / groupId > < artifactId > spring ‐ webmvc < / artifactId > < version > 5.1.5. RELEASE < / version > < / dependency > < the dependency > < groupId > javax.mail. Servlet < / groupId > < artifactId > javax.mail. Servlet ‐ API < / artifactId > <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId> Lombok </artifactId> <version>1.18.8</version> </dependencies> </dependencies> <build> The < finalName > security ‐ for springmvc < / finalName > < pluginManagement > < plugins > < plugin > < the groupId > org, apache tomcat. Maven < / groupId > < artifactId > tomcat7 ‐ maven ‐ plugin < / artifactId > < version > 2.2 < / version > < / plugin > < plugin > < groupId > org). Apache maven. Plugins < / groupId > < artifactId > maven ‐ compiler ‐ plugin < / artifactId > <configuration> <source> 1.8 < /source> <target>1.8</target> </configuration> </plugin> <artifactId> The < configuration > < encoding > utf 8 ‐ < / encoding > < useDefaultDelimiters >true</useDefaultDelimiters> 
<resources> 
<resource> 
<directory>src/main/resources</directory> 
<filtering>true</filtering> 
<includes> 
<include>**/*</include> 
</includes> 
</resource> 
<resource>
<directory>src/main/java</directory> 
<includes> 
<include>**/*.xml</include> 
</includes> 
</resource> 
</resources> 
</configuration> 
</plugin> 
</plugins> 
</pluginManagement> 
</build> 
</project> 
Copy the code

Spring Container Configuration

Define applicationConfig.java under the config package, which corresponds to the configuration of ContextLoaderListener in web.xml. This is where you configure everything except the SpringMVC controller.

Servletcontext configuration

In this case, webconfig. Java is defined under the config package in Servlet3.0 without web. XML, which corresponds to the DispatcherServlet configuration.

Loading the Spring container

In the init package define class SpringApplicationInitializer Spring container is initialized, such implementation WebApplicationInitializer interface, The Spring container load startup WebApplicationInitializer all interface implementation class.

SpringApplicationInitializer is equivalent to the web. The XML, use the servlet3.0 development does not need to define the web. XML, Applicationconfig. class corresponds to application-context. XML in the following configuration, and webconfig. class corresponds to spring-mVC.xml in the following configuration.

Implement authentication function

The certification page

In the webApp /WEB-INF/views definition of the authentication page login.jsp, this case only tests the authentication process, the page does not add CSS style, the page can actually fill in the user name, password, trigger login will submit form information to /login, the content is as follows:

Add the following configuration in WebConfig to direct/to the login.jsp page:

Start project, access/path address, test

Authentication interface

On the authentication page, enter the account and password, and click Login to request /login for identity authentication. (1) Define the authentication interface, which is used to verify the transmitted user name and password. If successful, the detailed information of the user will be returned; otherwise, an error exception will be thrown:

(2) Authentication implementation class, according to the user name search user information, and verify the password, here simulated two users:

(3) login to the Controller and process the /login request. It calls AuthenticationService to complete the authentication and returns the login result prompt message:

(4) Test start project, access/path address, test

Implement session function

Session refers to the process in which the system remembers the login status of the user after the user logs in to the system. The user can continue to operate in the system until the user logs out. The purpose of authentication is to protect system resources. Each access to resources, the system must know who is accessing the resources, so that the request can be intercepted. Therefore, after successful authentication, information about the successful user is stored in the Session. In subsequent requests, the system can obtain the current user from the Session to implement the Session mechanism. (1) Add Session control. Define a SESSION_USER_KEY in UserDto as the key for storing login user information in the Session.

Then modify the LoginController. After the authentication succeeds, add the user information to the current session. Add user logout method and set session as invalid when logout.

(2) Adding test resources Modify LoginController to add test resource 1, which obtains the current login user from the current session and returns a prompt message to the foreground.

(3) Direct access to test resources /r/ R1 without login:

Access test resource /r/ R1 in case of successful login:

The test result indicates that the user information is added to the session when the user logs in successfully, and subsequent requests can obtain the information of the previous login user from the session. The result is expected.

Enabling the Authorization Function

Now we have completed the verification of user identity credentials and login state retention, and we know how to obtain the information of the current logged-in user (obtained from Session). Next, users need to be authorized to access the system, that is, to complete the following functions: Disallow anonymous users from accessing certain resources. Login user access blocking: Determines whether a user can access certain resources based on the user’s permission. In order to achieve this function, we need to add a permission attribute in UserDto represent the permissions of the logged-in user, and modify the construction method of UserDto.

In AuthenticationServiceImpl initialization to simulate user permissions, including zhang SAN gave p1 permissions, li si to p2 permissions.

(2) Add test resource 2 to LoginController because we want different users to be able to access different resources if there are multiple resources.

(3) implement authorization interceptor define SimpleAuthenticationInterceptor blocker, in the context of the interceptor package be empowered intercept: 1, 2, check whether the user login, check whether the user has permissions

Configured interceptor in WebConfig, matching/r / * * for the protected system resources, access to the resource request into SimpleAuthenticationInterceptor interceptors.

(4) If the test is not logged in, “Please log in first” is displayed for/R/R1 and/R/R2. In the login case, John has the p1 permission and can access /r/ R1, while John does not have the P2 permission. When John accesses /r/ R2, a message “Insufficient permission” is displayed. In the login case, The user can access /r/ R2 because the user has p2 permission. The user does not have P1 permission. When the user accesses /r/ R1, a message is displayed indicating that the user has insufficient permission. All the test results are in line with the expected results. 5.8. Summary Session-based authentication is a common authentication method, which is still in use by many systems. In this section, we use the Spring MVC technique to implement it briefly, aiming to give you a clear and realistic understanding of the functional meaning and implementation of user authentication, authorization, and session, namely what they do respectively. What do you probably need to do? In formal production projects, we often consider the use of third-party security frameworks (such as Spring Security, Shiro and other security frameworks) to achieve authentication and authorization functions, because doing so can improve productivity to a certain extent, improve the degree of software standardization, and often the scalability of these frameworks is considered very comprehensive. However, the disadvantages are also very obvious. In order to improve the support range, these generic components will add many functions that we may not need, and the structure will be relatively abstract. If we do not understand it well, it will be difficult to locate problems once they occur.