首页 > 其他分享 >SpringSecurity认证授权完整流程

SpringSecurity认证授权完整流程

时间:2024-04-26 11:12:01浏览次数:24  
标签:SpringSecurity 流程 接口 认证 过滤器 权限 方法

SpringSecurity认证流程:loadUserByUsername()方法内部实现。

实现步骤:   

  1. 构建一个自定义的service接口,实现SpringSecurity的UserDetailService接口。
  2. 建一个service实现类,实现此loadUserByUsername方法。
  3. 调用登录的login接口,会经过authenticationManager.authenticate(authenticationToken)方法。此方法会调用loadUserByUsername方法。

 

  4.方法内部做用户信息的查询,判断用户名和密码是否正确,这是第一道认证。

 

  5.如果没有查到信息就抛出异常。

  6.如果查到信息了再接着查用户的权限信息,返回权限信息到loginUser实体。

  7.此实体实现了SpringSecurity自带的userDetail接口。实现了getAuthorities方法。

  .8每次查询权限都会调用此方法。

  9.查询到的权限,会被返回到login接口。进行后续操作。

  10.如果认证通过,通过身份信息中的userid生产一个jwt。

  11.把完整的用户信息作为value,token作为key存入redis。

 

  12.后续访问其他接口直接从redis中获取权限。

 

 

如何结合jwt登陆过滤器实现认证:

  1. 定义一个jwt登陆认证器,并交给spring容器管理。
  2. 在SpringSecurity配置中加入过滤器的配置。
  3. 请求会先经过此过滤器,然后会先获取token。
  4. 如果token为空,则放行,调用login接口进行认证的流程。
  5. 如果token不为空则判断是否合法。
  6. 如果token合法就会进行解析,从redis中取到用户信息。再封装进authenticationToken中,后续可以通过securityContext拿到认证信息。再放行。

 

SpringSecurity配置类如何定义?

  1. 密码要进行Bcrypt加密,所以要定义一个Bcrypt的bean。
  2. 认证是在SpringSecurity自带的authenticationManager中执行loadUserByUsername()方法实现的,所以要在此注入authenticationManager这个bean。
  3. 对于登录的login接口应实现匿名放行,其他接口要拦截,需要认证。
  4. 后续的鉴权是通过拿security中的authentication去跟接口上方的注解内标明的权限范围去做对比。
    所以要开启权限注解
  5.  

 

SpringSecurity的原理其实就是一个过滤器链,内部包含了提供各种功能的过滤器。这里我们可以看看入门案例中的过滤器

 

UsernamePasswordAuthenticationFilter:负责处理我们在登陆页面填写了用户名密码后的登陆请求。入门案例的认证工作主要有它负责。

ExceptionTranslationFilter处理过滤器链中抛出的任何AccessDeniedException和AuthenticationException 。

FilterSecurityInterceptor负责权限校验的过滤器。

 

我们可以通过Debug查看当前系统中SpringSecurity过滤器链中有哪些过滤器及它们的顺序

下图是完整的认证流程

 

一、UsernamePasswordAuthenticationFilter

这里是把我们的用户名密码传进来,用UsernamePasswordAuthenticationToken接收,

紧接着封装为authentication 对象

 

 二、UserDetailsService

多层的过滤器,嵌套调用方法,来到UserDetailsService

 把前面的用户名密码也传到这里了

来到UserDetailsService,第一个方法就是loadUserByUsername, 这个方法就需要我们自己去重写,一般就是到数据库的用户表去查询用户(这里并没有验证密码是否正确), 然后匹配到用户的话就会来查询权限,返回一个UserDetails 对象;否则就抛出异常。

三、密码校验

默认的密码检验规则一般都不是我们想要的,所以这里我们要自己选中密码校验规则,

 

也就是我们编码流程的注入PasswordEncode Bean对象 到Java 工厂 ,return  这里就是选择密码校验规则,我们选择的是bcrypt密码比对器

四、返回authentication 对象

五、自定义JWT 拦截器

 

此拦截器对应代码中的

 

 

 

授权基本流程

在SpringSecurity中,会使用默认的拦截器FilterSecurityInterceptor来进行权限校验。

在FilterSecurityInterceptor中会从SecurityContextHolder获取其中的Authentication,然

后获取其中的权限信息,最后判断当前用户是否拥有访问当前资源所需的权限。

因此在项目中只需要把当前登录用户的权限信息也存入Authentication。

然后设置我们的资源所需要的权限即可。

在代码中我们是这样操作的

 

先查询到用户的权限信息,在通过LoginUser进行封装。传入permissions

 

我们最终是要把permissions中的权限,转换为SimpleGrantedAuthority类型并封装到authorities中。

在用户第一次获取权限时,此时authorities为空,就会走下面的流程

将permission转类型然后存入authorities中。再返回。

这样在FilterSecurityInterceptor中会从SecurityContextHolder获取其中的Authentication,然后就可以拿到其中的authorities权限信息。

 

SpringSecurity为我们提供了基于注解的权限控制方案,这也是项目中主要采用的方式。

可以使用注解去指定访问对应的资源所需的权限。但是要使用它我们需要先开启相关配置

开启配置需要再在SpringSecurity的配置类中增加如下注解:

 

然后就可以在接口上添加注解,表示此接口必须要有注解中的权限信息。

 

除了使用自带的权限校验方法,我们也可以自定义权限校验方法。

自己写一个,代替LoginUser中的hasAuthority。

SPEL表达式中使用 @my相当于获取容器中bean的名字为ex的对象。然后再调用这个对象的hasAuthority方法。

 

这样就可以运用到自己定义的权限校验方法。

我们也可以在配置类中使用使用配置的方式对资源进行权限控制,但是这种方式用的并不多。但是有些地方,比如图片,访问图片不能也要写个方法去拿权限吧?登录也不能要权限吧?因为未登录都还没有进行认证授权。所以我们需要对某些资源进行白名单放行。

 

在securityConfig中配置。

自定义失败处理

如果希望在认证失败或者是授权失败的情况下也能和我们的接口一样返回相同结构的json,这样可以让前端能对响应进行统一的处理。要实现这个功能我们需要知道SpringSecurity的异常处理机制。

在SpringSecurity中,在认证或者授权的过程中出现了异常会被ExceptionTranslationFilter捕获到。

在ExceptionTranslationFilter中会去判断是认证失败还是授权失败出现的异常。

如果是认证过程中出现的异常会被封装成AuthenticationException然后调用AuthenticationEntryPoint对象的方法去进行异常处理。

如果是授权过程中出现的异常会被封装成AccessDeniedException然后调用AccessDeniedHandler对象的方法去进行异常处理。

所以如果我们需要自定义异常处理,我们只需要自定义AuthenticationEntryPoint和AccessDeniedHandler然后配置给SpringSecurity。

这是代码中定义的授权失败处理器

 

这是代码中定义的认证失败处理器

 

 

 

跨域

在SpringSecurity项目中配置springboot跨域可能会有问题。

所以要通过SpringSecurity来进行跨域配置

 

标签:SpringSecurity,流程,接口,认证,过滤器,权限,方法
From: https://www.cnblogs.com/wawaFish666/p/18159570

相关文章

  • DRF之三大认证【认证 权限 频率】
    DRF之三大认证【一】三大认证执行顺序【二】认证#我们如果想要自定义认证类,都需要继承【BaseAuthentication】fromrest_framework.authenticationimportBaseAuthentication【1】源码【2】认证类的使用###############################authentications.py#####......
  • 03、应急响应流程
    应急响应流程1.应急响应准备1.1.获取当前网络安全事件信息事件发生前,做好日常运维检测,收集各类故障信息区分系统自身故障和人为破坏区分一般事件和应急响应事件充分获取当前事件信息,从而启动相应的预案事件上报,确认应急事件类型和应急事件的等级通知相关人员,启动应急预......
  • 网络实名认证?企业如何实现实名认证?C++身份证实名认证接口
    身份证,大家都不陌生,现如今,我们用到身份证的地方越来越多,人们在办理很多业务时都会要求实名制,比如,电信实名制,火车票,汽车票实名制。为规范网络环境,前段时间国家也出台了相关政策,上网也需要网络实名制,就连大家常用的共享单车在注册时都会要求你实名制,那么,身份证是真是假,是如何确......
  • C++二要素认证,游戏实名认证接口、金融实名认证
    随着移动互联的发展,越来越多的企业在金融市场都想分一杯羹,而哪种理财产品才是人们放心的理财产品呢?我们都知道理财产品开户都需要上传身份证号核验和图像进行验证,以保证个人信息的真实性,那么这些是如何来判别身份证的真伪呢?加入上传一张假的身份证是否也能验证通过呢?翔云身份......
  • SpringBoot项目添加2FA双因素身份认证
    什么是2FA(双因素身份验证)?双因素身份验证(2FA)是一种安全系统,要求用户提供两种不同的身份验证方式才能访问某个系统或服务。国内普遍做短信验证码这种的用的比较少,不过在国外的网站中使用双因素身份验证的还是很多的。用户通过使用验证器扫描二维码,就能在app上获取登录的动态口令,......
  • Part-DB 配置流程
    介绍Part-DB是一个开源的器件管理工具,博主用于管理个人的电子器材,最近捣鼓了一下这个工具,由于手头还有一块闲置的赛昉·星光2的开发板,所以我打算一起拿来捣鼓一下,如果不成功,就用树莓派(生气......
  • 什么样的文件传输调度产品 可以简化IT工作流程?
    文件传输调度是企业数据管理中的一个重要环节,企业在存在多个分支机构、子公司,或者多个数据中心、服务器节点的时候,都会需要进行文件传输调度,在使用传统的FTP、rsync等传输方式在应对这些复杂的文件交换需求时,会存在诸多问题及挑战。  1、缺乏自动化策略:无法实现实时自动的数......
  • 微服务如何解决用户登录验证问题的流程整理
    0-我们通过客户端=》网关=》微服务的顺序访问服务端1-网关:这一步主要是获取token进行验证,成功后把用户信息保存到请求头以供微服务调取因为微服务模块比较多,如果每一个都写拦截器会造成不必要的冗余,所以我们统一把拦截器放在网关模块 网关的信息传递流程为客户端=》断言=》......
  • mysql慢sql优化流程
    #查询慢sqlselectdb,time,infofromINFORMATION_SCHEMA.processlistwhereinfoisnotnull;#查看执行计划explainSELECTCOUNT(1)FROMtables_nameWHEREvalid=1;#查看表索引showindexfromtables_name; #查看表数据selectcount(*)fromtables_nam......
  • 一个客户端请求 跟服务网关 服务器 服务后端之间的流程是什么样的?
    一个客户端请求经过服务网关到达服务器和服务后端的流程通常包括以下几个步骤:客户端发起请求:客户端发送请求到服务网关,请求可以是HTTP请求、RPC请求等。服务网关路由:服务网关接收到请求后,根据配置的路由规则将请求路由到相应的服务后端。路由规则可以根据......