21. Springboot_Security_ authentication and authorization

The two main goals of Spring Security are "authentication" and "authorization" (access control)

  • "Authentication"

Authentication is about verifying your credentials, such as username/user ID and password,以验证您的身份。

Authentication is usually done through a username and password, sometimes combined with authentication factors.

  • "Authorization"

Authorization occurs after the system successfully verifies your identity, and will eventually have 授予您访问资源full authority (such as information, files, databases, funds, locations, and almost any content).

Authentication and authorization

At present, our test environment can be accessed by anyone. We use Spring Security to add authentication and authorization functions

1. Introduce the Spring Security module

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2. Write basic configuration classes and define request authorization rules

@EnableWebSecurity // 开启WebSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
        // 定制请求的授权规则, 首页(/、index)所有人可以访问
        http.authorizeRequests()
                // 首页所有人可以访问
                .antMatchers("/","index").permitAll()
                //其他请求url分别设置角色权限才能进行访问
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
  }
}

3. Test it: I can't get in except the homepage! Because we currently do not have a logged-in role, it is only possible to request that the role that needs to log-in has the corresponding permissions!

4. Add the following configuration to the configure() method to enable the automatic configuration login function!

That is, define the access role permissions for the menu;

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 定制请求的授权规则, 首页(/、index)所有人可以访问
        http.authorizeRequests()
                // 首页所有人可以访问
                .antMatchers("/","index").permitAll()
                //其他请求url分别设置角色权限才能进行访问
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

//        http.formLogin().loginPage("/toLogin");
        //开启自动配置的登录功能:如果没有权限,就会跳转到登录页面!
        // /login 请求来到登录页
        // /login?error 重定向到这里表示登录失败
        http.formLogin();

5. Test it: It is found that when there is no permission, it will jump to the login page!

Insert picture description here

6. Define roles for users;

We can define authentication rules and define roles for users;

//定义认证规则
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
   
   //在内存中定义,也可以在jdbc中去拿....
   auth.inMemoryAuthentication()
          .withUser("wwj").password("123456").roles("vip2","vip3")
          .and()
          .withUser("root").password("123456").roles("vip1","vip2","vip3")
          .and()
          .withUser("guest").password("123456").roles("vip1","vip2");
}

7. Test, we can log in with these accounts to test! An error will be reported!

There is no PasswordEncoder mapped for the id “null”
Insert picture description here

8. The reason, we need to encrypt the password passed from the front end in some way, otherwise we will not be able to log in, modify the code

/定义认证规则
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
   //在内存中定义,也可以在jdbc中去拿....
   //Spring security 5.0中新增了多种加密方式,也改变了密码的格式。
   //要想我们的项目还能够正常登陆,需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密
   //spring security 官方推荐的是使用bcrypt加密方式。
   
   auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
          .withUser("wwj").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
          .and()
          .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
          .and()
          .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2");
}