Spring Security is one of the Security management frameworks in the Spring family. In fact, Spring Security has been developed for many years before Spring Boot, but it has not been used much.
Compared to Shiro, integrating Spring Security into SSM/SSH is a cumbersome operation, so Spring Security is more powerful than Shiro, But it’s not as useful as Shiro (although Shiro doesn’t have as many features as Spring Security, Shiro is sufficient for most projects).
Since Spring Boot has been available, Spring Boot has provided an automated configuration scheme for Spring Security that allows zero configuration of Spring Security.
So, in general, a common combination of security management technology stacks looks like this:
- SSM + Shiro
- Spring Boot/Spring Cloud + Spring Security
Note that this is only a recommended combination, but technically speaking, any combination will work.
Let’s see how it works.
1. Project creation
Using Spring Security in Spring Boot is very easy, just introduce dependencies:
Spring Security dependencies in POM.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Copy the code
Once you add a dependency, all of the project’s interfaces are automatically protected.
2. First experience
We create a HelloController:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(a) {
return "hello"; }}Copy the code
To access /hello, you need to log in.
When a user sends a request to access the /hello interface from the browser, the server returns a 302 response code to redirect the client to the /login page. After the user logs in to the /login page, the client is automatically redirected to the /hello interface.
In addition, you can also use POSTMAN to send requests. When sending a request with POSTMAN, you can put the user information in the request header (to avoid redirecting to the login page) :
Spring Security supports two different authentication methods based on the above two login methods:
- You can use the form to authenticate
- Authentication can be done using HttpBasic
3. Configure the user name
By default, the login user name is user, and the password is a string randomly generated when the project starts. The default password can be seen in the startup console logs:
This randomly generated password changes every time you start up. There are three different ways to configure the login user name and password:
- Configure it in application.properties
- Configured in memory through Java code
- Load from the database via Java
The first two are relatively simple, the third code volume is slightly large, this article will take a look at the first two, the third after a separate article to write an introduction, you can also refer to my micro personnel project.
3.1 Configuration File Configure the user name and password
You can configure basic user information directly in the application.properties file:
spring.security.user.name=javaboy
spring.security.user.password=123
Copy the code
When the configuration is complete, restart the project and you can log in using the username/password configured here.
3.2 Configuring the User Name and Password in Java
Can also configure the user name password in Java code, we first need to create a Spring Security configuration, integration since WebSecurityConfigurerAdapter class, as follows:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// The following two lines of configuration indicate that two users are configured in memory
auth.inMemoryAuthentication()
.withUser("javaboy").roles("admin").password("$2a$10$OR3VSksVAmCzc.7WeaRPR.t0wyCsIj24k0Bne8iKWV1o.V9wsP8Xe")
.and()
.withUser("lisi").roles("user").password("$2a$10$p1H8iWa8I4.CA.7Z8bwLjes91ZpY.rYREGHQEInNtAp4NzL6PLKxi");
}
@Bean
PasswordEncoder passwordEncoder(a) {
return newBCryptPasswordEncoder(); }}Copy the code
Here we configure two users in the configure method, the user password is encrypted string (plain text 123), starting from Spring5, mandatory password encryption, if you do not want to encrypt, It is possible to use NoOpPasswordEncoder, an instance of expired PasswordEncoder, but it is not recommended because it is unsafe.
Spring Security provides BCryptPasswordEncoder (BCryptPasswordEncoder), a password encoding tool, which can be very convenient to implement the password encryption and salt, the same plaintext encryption results are always different, so the user does not need to save additional salt fields, which is much more convenient than Shiro.
4. Log in and configure
For the login interface, the response after a successful login, the login response after the failure, we all can be configured in WebSecurityConfigurerAdapter implementation class. For example:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
VerifyCodeFilter verifyCodeFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);
http
.authorizeRequests()// Enable login configuration
.antMatchers("/hello").hasRole("admin")// To access the /hello interface, the admin role is required
.anyRequest().authenticated()// Represents the remaining interfaces, which can be accessed after login
.and()
.formLogin()
// Define the login page. If you access an interface that can be accessed only after you have logged in, you will be automatically redirected to this page
.loginPage("/login_p")
// Login processing interface
.loginProcessingUrl("/doLogin")
// define the key of the username for login, default is username
.usernameParameter("uname")
// Define the key of the user password for login, default is password
.passwordParameter("passwd")
// Log in to the successful processor
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
resp.setContentType("application/json; charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("success");
out.flush();
}
})
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException {
resp.setContentType("application/json; charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("fail");
out.flush();
}
})
.permitAll()// All interfaces related to form logins are passed directly
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
resp.setContentType("application/json; charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("logout success"); out.flush(); } }) .permitAll() .and() .httpBasic() .and() .csrf().disable(); }}Copy the code
In the successHandler method, you can configure a callback for a successful login. In the case of separate development, you can return JSON after a successful login. Similarly, in the failureHandler method, you can configure a callback for a failed login. In logoutSuccessHandler, a callback is configured for logging out successfully.
5. Ignore interceptions
If a request address does not need to be intercepted, there are two ways to do this:
- Set the address for anonymous access
- Filter the address directly, that is, the address does not go through the Spring Security filter chain
The second solution is recommended. The configuration is as follows:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/vercode"); }}Copy the code
Another powerful feature of Spring Security is that it can be used with OAuth2 to play with more tricks, which we will cover in a later article.
This article first said here, have a question welcome comment discussion.
Follow the public account [Jiangnan Little Rain], focus on Spring Boot+ micro service and the separation of the front and back end of the full stack technology, regular video tutorials to share, follow the reply to Java, get the Song brothers carefully prepared for you Java dry goods!