Introduction to spring security
What is spring security
Spring security is a spring based security framework. It provides a comprehensive security solution while handling authentication and authorization at the Web request level and method call level. Based on the Spring Framework, spring security makes full use of the functions of dependency injection (DI) and aspect oriented programming (AOP), provides declarative security access control functions for application systems, and reduces the work of writing a large number of duplicate codes for enterprise system security control. Is a lightweight security framework. It is well integrated with Spring MVC
spring security core functions
(1) Authentication (who are you, user / device / system)
(2) Verification (what can you do, also known as permission control / authorization, allowed operations).
Principle of spring security
Based on filter, servlet and AOP, identity authentication and authority verification are realized
spring security instance
On spring security
- Create maven project
- Add dependency: spring boot dependency, spring security dependency
<!--join spring boot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-parent</artifactId> <version>2.0.6.RELEASE</version> </parent> <!--web Development related dependencies--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--spring security--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
- Create Controller and receive request
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @author tao * @date 2021-04-04 9:45 * Summary: */ @Controller @RequestMapping() public class HelloSecurityController { @RequestMapping("/test1") @ResponseBody public String sayHello() { return "Hello Spring Secuirty Safety management framework"; } }
-
Framework generated users
User name: user
Password: the temporary password generated when the project is started. uuid
Password generated in log
generated security password: 9717464c-fafd-47b3-9995-2c18b24f7336 -
Customize user name and password
You need to set the login user name and password in the springboot configuration file
Create the spring boot configuration file under the resource directory
application.yml(application.properties)security: user: name: Nick password: Nick
Name: user defined name
Password: Custom password
-
Close validation
//Exclude the configuration of Security so that it is not enabled @SpringBootApplication(exclude = {SecurityAutoConfiguration.class}) //@SpringBootApplication public class SercurityTest1Application { public static void main(String[] args) { SpringApplication.run(SercurityTest1Application.class, args); } }
Use user information in memory
Using the user information in memory means simply configuring the user information in the memory of the server and configuring the corresponding permissions. It can be more flexible for function testing without using the database.
1) Use: WebSecurityConfigurerAdapter to control the content of security management.
What to do: inherit the WebSecurityConfigurerAdapter and override the method. realization
Custom authentication information. Override the following method.
protected void configure(AuthenticationManagerBuilder auth)
2) Spring Security version 5 requires the password to be encrypted, otherwise an error will be reported
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
Implement password encryption:
- Create an implementation class for encryption (select an encryption algorithm)
@Bean public PasswordEncoder passwordEncoder(){ //Create an implementation class of PasawordEncoder, which is an encryption algorithm return new BCryptPasswordEncoder(); }
- Encrypt each password
PasswordEncoder pe = passwordEncoder(); pe.encode("123456")
3) The example code is as follows
package cn.kt.sercurity_test1.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; /** * @author tao * @date 2021-04-04 10:39 * Summary: use user information in memory */ /* * @EnableGlobalMethodSecurity: Enable method level authentication * prePostEnabled: The default is false * true: Indicates that @ PreAuthorize and @ PostAuthorize can be used */ @Configuration @EnableWebSecurity public class MySecurityConfig { //In the method, the user and password information are configured as login information //Define two roles normal admin @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { PasswordEncoder pe = passwordEncoder(); auth.inMemoryAuthentication().withUser("admin").password(pe.encode("admin")).roles(); auth.inMemoryAuthentication().withUser("Nick").password(pe.encode("Nick")).roles(); auth.inMemoryAuthentication().withUser("Amy").password(pe.encode("Amy")).roles(); } //Create encryption class for password @Bean public PasswordEncoder passwordEncoder() { //Create an implementation class of PasswordEncoder, which is an encryption algorithm return new BCryptPasswordEncoder(); } }
Notes:
- @Configuration: indicates that the current class is a configuration class (equivalent to spring xml)
Configuration file), in this class, the return value of the method is java objects, which are put into
spring container. - @EnableWebSecurity: indicates the function of enabling the spring security security framework
- @Bean: put the returned value object of the method into the spring container.
Role based authentication
Role based implementation steps:
1. Set user's role
Inherit WebSecurityConfigurerAdapter
Override the configure method. Specifies the roles of the user
auth.inMemoryAuthentication().withUser("admin").password(pe.encode("admin")).roles("admin","normal");
2. Add the enable method level annotation on the class
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class MySecurityConfig extends WebSecurityConfigurerAdapter { }
After adding the @ EnableGlobalMethodSecurity(prePostEnabled = true) annotation, you can manually use @ PreAuthorize to specify the role authentication before the method and the role list that the method can access.
For example: hasAnyRole('role name 1 ',' role name N ');
package cn.kt.sercurity_test1.controller; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author tao * @date 2021-04-04 11:10 * Summary: */ @RestController public class AuthorizeSecurityController { //Specify a common method that both normal and admin can access @RequestMapping("/testUser") @PreAuthorize(value = "hasAnyRole('admin','normal')") public String testUser() { return "Hello Spring Secuirty normal and admin A common method that can be accessed"; } //Specify a proprietary method for admin access @RequestMapping("/testAdmin") @PreAuthorize(value = "hasAnyRole('admin')") public String testAdmin() { return "Hello Spring Secuirty admin Proprietary method of access"; } }
3. Or uniformly configure permissions in the configuration class
The configuration class is written as follows:
package cn.kt.securitytest2.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; // @EnableWebSecurity has automatically imported the Configuration annotation @ Configuration, which can be added without repetition @EnableWebSecurity public class MySecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //super.configure(http); //Authorization rules for custom requests http.authorizeRequests().antMatchers("/").permitAll() .antMatchers("/level1/**").hasRole("VIP1") .antMatchers("/level2/**").hasRole("VIP2") .antMatchers("/level3/**").hasRole("VIP3"); //Turn on the login function of automatic configuration, and the effect is that if you don't log in, you will come to the login page without permission http.formLogin().usernameParameter("user").passwordParameter("pwd") .loginPage("/userlogin"); //1,/login Go to the landing page //2,Redirect to / login?error indicates login failure //3,More details //4,The default post form of / login represents processing login, //5,After user-defined login, the default POST account is the username parameter, and the password parameter can be customized and modified through usernameParameter() and passwordParameter() //6,(I) customized loginPage; Then the post request of loginPage is login //Turn on the auto configured logoff function. http.logout().logoutSuccessUrl("/");//After logging off successfully, come to the home page //1,Accessing / logout means that the user logs off and clears the session //2,If the logout is successful, the / login?logout page will be returned; //Enable remember me function http.rememberMe().rememberMeParameter("remeber"); //After the login is successful, send the cookie to the browser for saving, and bring the cookie with you when you visit the page in the future. As long as you pass the check, you can avoid login //Clicking logoff will delete the cookie //The function of remembering me on your own login page needs to pass a Boolean parameter of remember me to judge whether you remember to log in. You can customize the parameter name I passed by rememberMeParameter() // Static resources and so on do not need authentication http.authorizeRequests().antMatchers( HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/webSocket/**" ).permitAll(); } //Define authentication rules @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //super.configure(auth); PasswordEncoder pe = passwordEncoder(); auth.inMemoryAuthentication() .withUser("zhangsan").password(pe.encode("123456")).roles("VIP1", "VIP2") .and() .withUser("lisi").password(pe.encode("123456")).roles("VIP2", "VIP3") .and() .withUser("wangwu").password(pe.encode("123456")).roles("VIP1", "VIP3"); } //Create encryption class for password @Bean public PasswordEncoder passwordEncoder() { //Create an implementation class of PasawordEncoder, which is an encryption algorithm return new BCryptPasswordEncoder(); } }
be careful:
- Override the protected void configure(HttpSecurity http) throws Exception {} method for authorization control
- http.authorizeRequests().antMatchers("/").permitAll() means that everyone can access the "/" home page; http.authorizeRequests().antMatchers("/level1/**").hasRole("VIP1") means that only people with "VIP1" permission can access the contents under the "/ level1/xxx" page. Accordingly, it is necessary to add static resources without authorization.
- http.formLogin() enables the login function of automatic configuration. Effect: if you do not log in, you will come to the login page without permission. Accordingly, you can also define the login rules according to the comments in the code
- http.logout().logoutSuccessUrl("/") enables the auto configured logout function. After successful logout, go to the home page and clear the session
- http.rememberMe() enables the remember me function, and will send the cookie to the browser for saving. Later, visit the page with this cookie. As long as you pass the check, you can avoid login