SpringSecurity详细解读与应用

589 阅读2分钟

SpringSecurity又称安全框架,拥有基于用户的 '认证' + '权限' 两大功能; 1.用户认证:验证该用户是否为数据库中存储的数据; 2.权限授予:对于不同的用户给予不同访问权限,给出对于项目中不同功能/视图的是否可访问; (视频教程地址:https://www.bilibili.com/video/BV1mm4y1X7Hc?p=1)

用户认证

原生的Security框架在项目启动后,发送任意的请求,都会调用用户认证API:/login。输入框架分配的username和password,我们可以重新部分接口的实现方法,使username和password可以来自数据库。 image.png

执行流程:

图片.png

1、在登陆时用户输入username和明文password,封装到UserDetails中;

d39775acc9bfe39c163d7ffd2bb617b.png

2、框架根据UserDetails提供的username查询数据库中的用户,封装到Authentication中;

3866fc1c3f27995075e34526c585a2f.png

3、框架将UserDetails的密码与Authentication的密码进行校对

29ea44b218bd4de89ce4b446025556a.png

4、校对不通过认证失败;校对通过,则根据username和password生成Token令牌

99988aa1e26a6128d99fd4e415f3e0f.png

5、编辑请求过滤器OncePerRequestFilter,使前端发送请求后,后端可以在Controller执行前获取请求数据是否携带token,不携带则拒绝访问

28c75df9b4d41d77d36af1de3950a4f.png

6、框架所需的配置类,包含重新定义密码加密校验方式BCrypt、放行登录、登出等不需要token的接口

9b53aea49dbccc7a8574da8dea690c6.png

代码实现:

1、创建自定义登录接口

在Controller新建user/login接口,并在将此接口在Security配置类中设置放行,不受Security管理; (1)定义登录接口

    @RestController
    @RequestMapping("/user")
    public class UserController {

        @Autowired
        LoginService loginService;

        /**
         * 校验用户名和密码;
         * 验证成功根据用户名和密码生成token;
         * 返回token响应前端;
         * @param infoUser;
         */
        @PostMapping("/login")
        public Result login(@RequestBody User infoUser){
            return loginService.login(infoUser);
        }
    }
    @Service
    public class loginServiceImpl implements LoginService {
        @Override
        public Result<HashMap<String,String>> login(@RequestBody User userInfo) {
            return Result.ok(null);
        }
    }

(2)配置类放行该接口

    @Configuration
    public class securityConfig extends WebSecurityConfigurerAdapter {
        /** todo 定义放行接口 */
        @Override
        protected void configure(HttpSecurity http) throws Exception{
            http.
                csrf().disable()//关闭csrf
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) //前后端分离不需要session
                .and()
                .authorizeRequests().antMatchers("/user/login").anonymous()// 放行接口,请求可以匿名访问,不受Security管理
                .anyRequest().authenticated();//除上面外的所有请求都需要认证用户
        }
    }