preface
Security is definitely important in Web application development, and Spring Security is a good choice to protect web applications. Spring Security is a Security module in the Spring project that makes it easy to integrate seamlessly with Spring projects. In particular, adding Spring Security to your Spring Boot project is easy. This article introduces Spring Security and its use in Web applications. Get started today with our first section of Getting started with Spring Security!
Let’s cut to the chase
Create an unprotected application
Suppose we have now created a SpringBoot Web application with a controller as follows:
@Controller
@RequestMapping("/sa")
public class HelloContoller {
@RequestMapping("/hello")
@ResponseBody
public String test() {return "Hello ,spring security!"; }}Copy the code
As we can see, this is a simple SpringBoot project. Then we start the application, assuming that port is 8080, so when we visit http://localhost:8080/sa/hello in the browser can see Hello in the browser, spring security! .
We need to understand. This request is accessible to anyone. The next. We added Spring Security to protect the application
We added the Spring Security dependency to the POM file
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Copy the code
Let’s log in again when they visit http://localhost:8080/sa/hello
This page is the default login page provided by Spring Security. Let’s log in. The default username is user, and if you’re careful, you’ll notice that the console prints a strange string of characters when you launch the app. Yes, that’s the password
We can also customize the user name and password instead of using what Spring Security provides us. We add the following code to the application.properties file
spring.security.user.name=admin
spring.security.user.password=admin
Copy the code
Here I have a custom user with both the username and password admin. Restart the project and you will notice that the console does not provide us with a random password. Then you use the username and password you set to log in will also be able to give you a message
Role-resource access control
In general, we need to implement “certain resources can only be accessed by certain roles”. Suppose our system has the following two roles:
ADMIN can access all resources
USER can only access specific resources
Now we add “/product” to the system to represent the product information resources (USER can access); Add resources for the /admin code administrator (not accessible to USER). The code is as follows:
@controller@requestMapping ("/admin")
public class AdminController {
@RequestMapping("/info")
@ResponseBody
public String info() {return "Welcome to the admin page, you're the admin."; }}Copy the code
@controller@requestMapping ("/product")
public class ProductController {
@RequestMapping("/info")
@ResponseBody
public String info() {return "Welcome back to the supplier page, where you are a regular user."; }}Copy the code
In a formal application, our users and roles are stored in a database; For the sake of this example, let’s create two users and roles that are stored in memory. We create SecurityConfiguration increase role user configuration class, this class inherits WebSecurityConfigurerAdapter classes, we rewrite the configure method here. The following code:
@ Configuration @ EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter {/ * in formal application, Our users and roles are stored in the database for easy demonstration. We create users and roles in the memory * / / / to create User User and Admin protected void the configure (AuthenticationManagerBuilder auth) throws the Exception { auth.inMemoryAuthentication() .withUser("yyw") // The administrator has admin and user permissions and can access all resources. Password ("123456"// Administrator password.roles("ADMIN"."USER") // Set admin and user permissions. And ().withuser ()"zs"// Common users can only access /product/**.password("123456"// Common user password.roles("USER"); Protected void configure(HttpSecurity HttpSecurity) throws Exception{ httpSecurity.authorizeRequests() .antMatchers("/product/**").hasRole("USER") // Assign accessible resources to the user role. AntMatchers ("/admin/**").hasRole("ADMIN"AnyRequest ().authenticated().and().formLogin().and().httpbasic (); }}Copy the code
Note that Spring Boot 2.0.3 references the security dependency of Spring Security 5.X. This version must provide an instance of PasswordEncorder, otherwise the background will report an error.
Therefore, you need to create an implementation class for PasswordEncorder. Here we define an MyPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder;
public class MyPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
returns.equals(charSequence.toString()); }}Copy the code
We then add this line to the Configure method of the SecurityConfiguration class we defined above
protected void configure(AuthenticationManagerBuilder auth) throws Exception{ Auth. InMemoryAuthentication (.) passwordEncoder (new MyPasswordEncoder ()) / / plus the withUser ("yyw") // The administrator has admin and user permissions and can access all resources. Password ("123456"// Administrator password.roles("ADMIN"."USER") // Set admin and user permissions. And ().withuser ()"zs"// Common users can only access /product/**.password("123456"// Common user password.roles("USER"); // Set user privileges}Copy the code
The following to verify that the average user login, restart the project, type http://localhost:8080/admin/info in your browser. Similarly, we will arrive at the login page, we enter username ZS, password is also 123456 result error page, denied access, message:
There was an unexpected error (type=Forbidden, status=403).
Access is denied
Copy the code
We changed the uri in the browser to: /product/info, and the access succeeded. You can see the welcome back to the supplier page, where you are a regular user. Zs can only access product/**, which is as expected.
To verify the administrator user login, after restart your browser, enter http://localhost:8080/admin/info. On the login page, enter the user name yyw and password 123456. After the submission, you can see the information, indicating that you can access administrator resources. Then we changed the browser URI to /product/info. After refreshing, we can also see the printed information, indicating that YYW users can access all resources, which is also consistent with our expectation.
Let’s recall that we did not add sa/ Hello to roles and permissions in HelloContoller. If we access sa/hello as admin, we’ll find that we can also return messages. If we switch back to user, we’ll find that we can also return messages. From this we draw a conclusion
As long as the request path is not configured in the following methods, anyone can access it. So let’s verify that. We configure requests for sa/** under the ADMIN role
protected void configure(HttpSecurity httpSecurity) throws Exception{
httpSecurity.authorizeRequests()
.antMatchers("/product/**").hasRole("USER") // Assign accessible resources to the user role. AntMatchers ("/admin/**"."/sa/**").hasRole("ADMIN"AnyRequest ().authenticated().and().formLogin().and().httpbasic (); }Copy the code
We restart the project again. You will notice that only the admin user can access the hello request
We can also get information about the currently logged in user
Above we have achieved “resource – role” access control, the effect is consistent with our expectations, but not intuitive, we might as well try to get the “current login user” information in the controller, direct output, see the effect. Modify the sa/ Hello request method
@RequestMapping("/hello")
public String test(){
String currentUser = ""; // We get user information Object Principl = via SecurityContextHolder SecurityContextHolder.getContext().getAuthentication().getPrincipal();if(principl instanceof UserDetails) {
currentUser = ((UserDetails)principl).getUsername();
}else {
currentUser = principl.toString();
}
return " some sa hello,currentUser is: "+currentUser;
}
Copy the code
Starting the project, let’s revisit the Hello request and see that the page outputs user information
summary
At this point, we have a basic understanding of Spring Security. You learned how to add Spring Security to your project and how to control role access control for resources. Spring Security is more than that, and we’re just getting started. To better use Spring Security in the real world we need a deeper understanding. All right, let’s call it a day. See you next time!
The copyright of this article belongs to the code of swimming, please indicate the source. If the article is not enough, welcome to point, the follow-up will be improved.
If this article is helpful to you, please give me a like. Thank you very much!