一下午在实训教室闷得不行,中午没睡觉,脑子有点糊,不在状态啊,话不多说,又是一个头疼的下午。

来了,来了,他真的来了,这个无知的小白又来写博客霍霍人了

强调两点 认证与授权,WebSecurityConfig依赖于MyUserDatailService

在项目的启动的时候WebSecurityConfig,MyUserDatailService就会被实例化,随时可以使用

1.引入springSecurity模块

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

2.编写springSecurity配置类,配置角色,定制Http的安全规则,配置匹配路径与权限
请求controller也就是请求http,经过 MyUserDatailService 的 configure(HttpSecurity http) 过滤中查看是否需要权限

   @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers(HttpMethod.POST,"/add-user").permitAll()// 允许post请求/add-user访问
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("admin")
                .antMatchers("/level2/**").hasRole("user")
                .antMatchers("/level3/**").hasRole("admin")
               // .anyRequest().authenticated() // 所有请求都需要验证
                .and()
                .formLogin().loginPage("/userlogin").loginProcessingUrl("/authentication/form")// 使用默认的登录页面
                .and()
                .logout().logoutSuccessUrl("/")
                .and()
                .csrf().disable();// post请求要关闭csrf验证,不然访问报错
    }

3.需要权限就去验证,然后就让 configure(AuthenticationManagerBuilder auth)验证,要验证就要有两个对象,一个是用户输入的,一个是数据库中的,

    @Autowired
    private MyUserDatailService userDetailService;

  @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //用户的输入与其对比,成功准许通过
        // 验证身份就是加载响应的userDetailServic,看看是否和用户输入的账号、密码、权限等信息匹配
        auth
                .userDetailsService(userDetailService)
                //认证规则的密码
                .passwordEncoder(passwordEncoder());
    }

4.上文的 userDetailService 就是根据用户输入的用户名,找到之后返回一个对象,注意返回对象,注意这里是 WebSecurityConfig 依赖于 MyUserDatailService
所以执行 configure(AuthenticationManagerBuilder auth) 就必须调用 MyUserDatailService 类来获得数据库对象

package com.example.demo.config;

import com.example.demo.Services.UserService;
import com.example.demo.entity.Userinfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class MyUserDatailService implements UserDetailsService {
    @Autowired
    private UserService userService;
    //这里就是service层,负责调用dao层来查找用户
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        
            Userinfo user = userService.selectUserByUsername(username);
            //根据用户名取出数据库的这个对象
            if (user == null){
                System.out.print("用户不存在");
                throw new UsernameNotFoundException("该用户不存在");
            }
            //角色一定要是ROLE_形式
            List<GrantedAuthority> authorities = new ArrayList<>();
            authorities.add(new SimpleGrantedAuthority("ROLE_" + user.getRole()));

            //从数据库中取回的对象加上权限
            return new User(
                    user.getUsername(),
                    user.getPassword(),//这里的密码是数据库中加密后的
                    authorities
            );
        }
}

5.用户查找完毕后,返回,然后与 configure(AuthenticationManagerBuilder auth) 定义的规则进行匹配,成功就可以通过验证,此时userDetailService为数据库查出的对象,密码因为在添加的时候带了加密功能,所以要在passwordEncoder配置密码规则 auto .passwordEncoder(new MyPasswordEncoder(),这样,页面提交时候,密码以明文的方式进行匹配。和用户的输入方式正好匹配

注意:这个无知的小白正在处于初级阶段,不要特别相信,写这个是小白的自我理解,如有错误,请指出,必改正。