史诗级的SpringSecurity的认证授权的相关概念及流程讲解!!!

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

前言

Web应用的开发安全是至关重要的选择使用SpringSecurity是目前来说较为正确的选择。SpringSecurity框架起源于2003年年底acegi系统起因是 Spring开发者邮件列表中的一个问题,有人提问是否考虑提供一个基于Spring的安全实现。

基于SpringBoot+MP+Redis+Vue实现的前后端分离的权限管理系统
https://gitee.com/xwrich/authority

一、SpringSecurity简介

Spring 是非常流行和成功的 Java 应用开发框架而Spring Security 正是其中的一员。Spring Security 基于 Spring 框架提供了一套 Web 应用安全性的完整解决方案。
关于安全方面的两个核心功能是“认证”和“授权”一般来说Web 应用的安全性包括**用户认证Authentication和用户授权Authorization**两个部分这两点也是 SpringSecurity 重要核心功能。
1用户认证验证某个用户是否为系统中的合法主体也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码系统通过校验用户名和密码来完成认证过程。
2用户授权验证某个用户是否有权限执行某个操作。在一个系统中不同用户所具有的权限是不同的。比如对一个文件来说有的用户只能进行读取而有的用户可以进行修改。一般来说系统会为不同的用户分配不同的角色而每个角色则对应一系列的权限。

二、Shiro和Security的对比

2.1 Shiro的特点

  • 轻量级。主张的理念是把复杂的事情变简单。针对对性能有更高要求的互联网应用有更好表现。
  • 通用性。不局限于 Web 环境可以脱离 Web 环境使用。
  • 依赖性低。不需要任何框架和容器可以独立运行
  • 配置和使用比较简单

Shiro的三个核心组件Subject、SecurityManager 和 Realms。

2.2 Security的特点

  • 全面的权限控制。
  • 专门为 Web 开发而设计。
  • Spring Security 依赖Spring容器
  • 新版本对整个框架进行了分层抽取分成了核心模块和 Web 模块。单独引入核心模块就可以脱离 Web 环境。

2.3 二者的相同点

  • 认证功能
  • 授权功能
  • 加密功能
  • 会话管理
  • 缓存支持
  • rememberMe功能

基于以上一般来说常见的安全管理技术栈的组合是这样的

• SSM + Shiro
• Spring Boot/Spring Cloud + Spring Security

三、Security实现权限

若要对Web资源进行保护最好的办法是使用Filter对方法调用进行保护当然也可以使用AOP的方式。
Spring Security进行认证和鉴权的时候就是利用的一系列的Filter来进行拦截的。
在这里插入图片描述一个请求想要访问到API就会从左到右经过蓝线框里的过滤器其中绿色部分是负责认证的过滤器蓝色部分是负责异常处理橙色部分则是负责授权。进过一系列拦截最终访问到我们的API。

这里面我们只需要重点关注两个过滤器即可UsernamePasswordAuthenticationFilter负责登录认证FilterSecurityInterceptor负责权限授权

说明Spring Security的核心逻辑全在这一套过滤器中过滤器里会调用各种组件完成功能掌握了这些过滤器和组件就掌握了Spring Security这个框架的使用方式就是对这些过滤器和组件进行扩展。

四、用户认证流程

在这里插入图片描述
当前登录用户在Spring Security中的体现就是 Authentication它存储了认证信息代表当前登录用户。使用时通过 SecurityContext 来获取AuthenticationSecurityContext就是我们的上下文对象这个上下文对象则是交由 SecurityContextHolder 进行管理。你可以这样使用

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

SecurityContextHolder原理非常简单就是使用ThreadLocal来保证一个线程中传递同一个对象。

Spring Security中三个核心组件
1、Authentication存储了认证信息代表当前登录用户
​2、SeucirtyContext上下文对象用来获取Authentication
3、SecurityContextHolder上下文管理对象用来在程序任何地方获取SecurityContext

Authentication中的信息包含
1、Principal用户信息没有认证时一般是用户名认证后一般是用户对象
2、Credentials用户凭证一般是密码
​3、Authorities用户权限

Spring Security用户认证关键代码

// 生成一个包含账号密码的认证信息
Authentication authenticationToken = new UsernamePasswordAuthenticationToken(username, passwrod);
// AuthenticationManager校验这个认证信息返回一个已认证的Authentication
Authentication authentication = authenticationManager.authenticate(authenticationToken);
// 将返回的Authentication存到上下文中
SecurityContextHolder.getContext().setAuthentication(authentication);

4.1 认证接口分析

AuthenticationManager的校验逻辑
根据用户名先查询出用户对象没有查到则抛出异常将用户对象的密码和传递过来的密码进行校验密码不匹配则抛出异常。

根据用户名查询出用户对象交由UserDetialsService接口处理该接口只有一个方法loadUserByUsername(String username)通过用户名查询用户对象默认实现是在内存中查询。

查询出来的用户对象需要通过Spring Security中的用户数据UserDetails 实体类来体现该接口中提供了账号、密码等通用属性。

对密码进行校验使用PasswordEncoder组件负责密码加密与校验。

看下AuthenticationManager校验逻辑的大概源码

public Authentication authenticate(Authentication authentication) throws AuthenticationException {
...省略其他代码

    // 传递过来的用户名
    String username = authentication.getName();
    // 调用UserDetailService的方法通过用户名查询出用户对象UserDetail查询不出来UserDetailService则会抛出异常
    UserDetails userDetails = this.getUserDetailsService().loadUserByUsername(username);
    String presentedPassword = authentication.getCredentials().toString();

    // 传递过来的密码
    String password = authentication.getCredentials().toString();
    // 使用密码解析器PasswordEncoder传递过来的密码是否和真实的用户密码匹配
    if (!passwordEncoder.matches(password, userDetails.getPassword())) {
        // 密码错误则抛出异常
        throw new BadCredentialsException("错误信息...");
    }

    // 这里返回的已认证Authentication是将整个UserDetails放进去充当Principal
    UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(userDetails,
            authentication.getCredentials(), userDetails.getAuthorities());
    return result;

...省略其他代码
}

UserDetialsServiceUserDetailsPasswordEncoder这三个组件Spring Security都有默认实现但是满足不了我们的实际需求所以需要我们自己来实现这些组件。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring