当前位置: 首页 > 知识库问答 >
问题:

在Spring Security中使用安全API时,调用的顺序是什么?

马俊
2023-03-14

我是学习Spring的新手。我能找到的资源不多,无法解释当我们在Spring遇到安全API时会发生什么的事件顺序。

考虑以下场景:

我想让用户通过点击 /authenticateendpoint来登录。

在这种情况下,我可以看到涉及到几个不同的类:

1)WebSecurityConfigAdapter(允许我们指定安全性以及哪些角色可以访问特定endpoint)

2)OncePerRequest estFilter类(拦截每个请求,验证它并在上下文中设置当前经过身份验证的主体)

3)身份验证提供者类

4)抽象身份验证令牌类

在api调用的生命周期中何时何地调用这些类。有人能帮助我理解或指给我一个从序列角度清楚地解释它的资源吗

共有1个答案

宣俊豪
2023-03-14

Spring Security是一个基于过滤器的框架,它在代理过滤器或Spring托管bean方面在您的应用程序之前放置了一个WALL(HttpFireWall)。您的请求必须通过多个过滤器才能到达您的API。

>

  • WebAsyncManagerIntegrationFilter提供SecurityContext和Spring Web的WebAsyncManager之间的集成

    SecurityContextPersistenceFilter此筛选器将仅在每个请求中执行一次,使用在请求之前从配置的SecurityContextRepository获得的信息填充SecurityContextHolder,并在请求完成并清除上下文持有人后将其存储回存储库
    已检查现有会话的请求。若有新请求,将创建SecurityContext;若请求有会话,则将从respository获取现有安全上下文。

    HeaderWriterFilter过滤实现,将头添加到当前响应中。

    如果请求url为注销(默认配置),或者如果请求url匹配器在注销配置器中配置,则

    • 清除安全上下文
    • 使会话无效
    • 删除在LogoutConfigurer中配置了cookie名称的所有cookie
    • 重定向到已配置的默认注销成功url或注销成功url,或调用已配置的logoutSuccessHandler

    用户名密码认证过滤器

    • 对于loginProcessingUrl以外的任何请求url,此筛选器将不会进一步处理,但筛选器链将继续
    • 如果请求的URL为matches(必须是HTTP POST),则默认为login或matches。loginProcessingUrl()在FormLoginConfigurer中配置,然后尝试身份验证
    • 默认登录表单参数为用户名和密码,可由用户名参数(字符串)和密码参数(字符串)覆盖
    • 设置<代码>。loginPage()覆盖默认值
    • 尝试身份验证时
      • 将创建一个身份验证对象(UsernamePasswordAuthenticationToken或自定义身份验证筛选器中身份验证的任何实现)
      • 和authenticationManager。将调用authenticate(authToken)
      • 请注意,我们可以配置任意数量的AuthenticationProvider,authentication方法尝试所有身份验证提供程序并检查任何身份验证提供程序支持的身份验证令牌/身份验证对象,支持的身份验证提供程序将用于身份验证。如果身份验证成功,则返回身份验证对象,否则将引发AuthenticationException

      如果您使用SecurityContextHolderAwareRequestFilter将Spring Security感知HttpServletRequestWrapper安装到servlet容器中

      检测SecurityContextHolder中是否没有身份验证对象,如果没有找到身份验证对象,则创建具有授予权限的身份验证对象(匿名身份验证令牌)ROLE_ANONYMOUS。这里匿名身份验证令牌有助于识别未身份验证用户的后续请求。

      DEBUG - /app/admin/app-config at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
      DEBUG - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@aeef7b36: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' 
      

      ExceptionTranslationFilter,用于捕获任何Spring Security异常,以便可以返回HTTP错误响应或启动适当的AuthenticationEntryPoint

      FilterSecurityInterceptor
      将有FilterSecurityInterceptor几乎是过滤器链中的最后一个,它从SecurityContext获取身份验证对象并获得授予权限列表(授予角色),它将决定是否允许此请求到达请求的资源,决定是通过与在HttpSecurityConfiguration中配置的允许的AntMatcher进行匹配。

      将例外情况401视为未经授权,403视为禁止。这些决策将在过滤器链的最后一个环节完成

      • 未通过身份验证的用户尝试访问公共资源-允许
      • 未通过身份验证的用户尝试访问安全资源-401-UnAuthorize
      • 尝试访问受限资源(因其角色而受限)的经过身份验证的用户-403-禁止

      注意:用户请求流不仅存在于上述过滤器中,这里也没有显示其他过滤器。(<代码>ConcurrentSessionFilter,<代码>RequestCacheAwareFilter,<代码>SessionManagement Filter…)
      使用自定义身份验证过滤器而不是用户名密码身份验证过滤器时,情况会有所不同
      如果配置JWT auth filter并忽略,则情况会有所不同。formLogin()即UsernamePasswordAuthenticationFilter,它将变成完全不同的情况。

      根据文档,过滤器的顺序如下所示

      • 通道处理过滤器

      您还可以参考
      对现代Web应用程序进行身份验证的最常见方法?
      Spring Security上下文中身份验证和授权之间的区别?

  •  类似资料:
    • 本文向大家介绍如何使用SpringSecurity保护程序安全,包括了如何使用SpringSecurity保护程序安全的使用技巧和注意事项,需要的朋友参考一下 首先,引入依赖: 引入此依赖之后,你的web程序将拥有以下功能: 所有请求路径都需要认证 不需要特定的角色和权限 没有登录页面,使用HTTP基本身份认证 只有一个用户,名称为user 配置SpringSecurity springsecur

    • 问题内容: 假设我的web.xml中有以下内容 如果请求以/XYZ/abc.do的形式出现,过滤器的调用顺序是什么?为什么? 问题答案: 按照其映射在web.xml中定义的顺序 如果使用注释(),则顺序似乎未定义 -您仍必须在web.xml中声明条目。

    • 问题内容: 如果我在顺序流上调用collect(例如,从调用Collection.stream()中调用),那么它将使用我传递来进行收集的combiner参数吗?我认为不是,但在文档中什么也看不到。如果我是正确的,那么似乎不得不提供我知道不会使用的东西(如果我知道它是顺序流),这似乎是不幸的。 问题答案: 请记住要根据接口规范进行开发-而不要针对实现进行开发。下一Java版本可能会更改实现,而规范

    • 如果我在序列流上调用collect(例如从调用Collection.stream()),那么它会使用我传递给collect的合并器参数吗?我想没有,但我在文件中什么也没看到。如果我是正确的,那么很遗憾必须提供一些我知道不会使用的东西(如果我知道它是一个顺序流)。

    • 使用@Caching注释,spring允许向单个方法添加多个@Cacheable注释。由于可以使用@Cacheable进行条件缓存,因此注释和条件的计算顺序是什么?如果多个缓存的计算结果为true,则值是否存储在多个缓存中?同样,在缓存获取期间,是否并行计算所有条件,并从条件计算为true的任何缓存中获取值? 例如:

    • 我发现了一个非常奇怪的行为查看寻呼机。在使用FragmentPagerAdapter时,我观察到getItem()的调用顺序正确,即位置0、位置1、位置2......但onCreateView()的调用顺序相反,即位置2、位置1、位置0。(假设viewpager维护3个屏幕外页面)我认为,viewpager维护了一堆这些片段。当需要创建视图时,它从堆栈中弹出顶部最活跃的片段,并使其调用onCrea