Spring Security - 架构



Spring Security 是 Spring 项目或模块之一,用于保护基于 Spring 的应用程序。Spring Security 为我们提供了许多内置功能来在我们的应用程序中实现身份验证和授权。我们可以使用这些功能并进行修改,从而快速保护应用程序。除此之外,Spring Security 还允许对之前提到的功能进行大量自定义,以实现我们自己的复杂身份验证和授权。

Spring Security 架构

Spring Security 架构从 Servlet 过滤器开始。这些过滤器拦截请求,对请求执行操作,然后将请求传递给过滤器链中的下一个过滤器或请求处理程序,或者如果请求不满足某些条件则阻止请求。正是在此过程中,Spring Security 可以对请求进行身份验证并在请求上执行各种身份验证检查。它还可以通过不允许未经身份验证或恶意请求通过来阻止它们访问受保护的资源,从而保护我们的应用程序和资源。因此,我们的应用程序和资源保持受保护。

Components of Spring Security Architecture

Spring Security 架构的组件

如上图所示,Spring Security 的基本组件如下所示。在后续内容中,我们将简要讨论它们。我们还将讨论它们在身份验证和授权过程中的作用。

如上图所示,Spring Security 的基本组件如下所示。在后续内容中,我们将简要讨论它们。我们还将讨论它们在身份验证和授权过程中的作用。

AuthenticationFilter

这是拦截请求并尝试对其进行身份验证的过滤器。在 Spring Security 中,它将请求转换为 Authentication 对象,并将身份验证委托给 AuthenticationManager。

AuthenticationManager

它是身份验证的主要策略接口。它使用唯一的 authenticate() 方法来对请求进行身份验证。authenticate() 方法执行身份验证,并在身份验证成功时返回 Authentication 对象,或者在身份验证失败时抛出 AuthenticationException。如果该方法无法决定,则将返回 null。在此过程中,身份验证过程委托给 AuthenticationProvider,我们将在后面讨论。

AuthenticationProvider

ProviderManager 实现 AuthenticationManager,并将过程委托给一个或多个 AuthenticationProvider 实例。任何实现 AuthenticationProvider 接口的类都必须实现两个方法——authenticate() 和 supports()。首先,让我们讨论 supports() 方法。它用于检查我们的 AuthenticationProvider 实现类是否支持特定的身份验证类型。如果支持则返回 true,否则返回 false。接下来是 authenticate() 方法。这是发生身份验证的地方。如果支持身份验证类型,则启动身份验证过程。在此类中,可以使用 **UserDetailsService** 实现的 loadUserByUsername() 方法。如果找不到用户,则可以抛出 UsernameNotFoundException。

另一方面,如果找到用户,则使用用户的身份验证详细信息来对用户进行身份验证。例如,在基本身份验证方案中,用户提供的密码可能会与数据库中的密码进行检查。如果发现它们彼此匹配,则表示成功。然后,我们可以从此方法返回一个 Authentication 对象,该对象将存储在 Security Context 中,我们将在后面讨论。

UserDetailsService

它是 Spring Security 的核心接口之一。任何请求的身份验证大多取决于 UserDetailsService 接口的实现。它最常用于数据库支持的身份验证以检索用户数据。数据是通过实现唯一的 loadUserByUsername() 方法检索的,我们可以在其中提供我们的逻辑来获取用户的用户详细信息。如果未找到用户,该方法将抛出 UsernameNotFoundException。

PasswordEncoder

在 Spring Security 4 之前,PasswordEncoder 的使用是可选的。用户可以使用内存中身份验证存储纯文本密码。但是 Spring Security 5 已强制使用 PasswordEncoder 来存储密码。它使用其众多实现之一对用户的密码进行编码。其最常见的实现是 BCryptPasswordEncoder。此外,我们可以将 NoOpPasswordEncoder 的实例用于开发目的。它将允许密码以纯文本形式存储。但它不应用于生产或真实世界的应用程序。

Spring Security Context

这是在身份验证成功后存储当前已认证用户详细信息的地方。然后,身份验证对象在整个会话期间对应用程序可用。因此,如果我们需要用户名或任何其他用户详细信息,我们需要先获取 SecurityContext。这是通过 SecurityContextHolder 完成的,SecurityContextHolder 是一个辅助类,提供对安全上下文的访问。我们可以分别使用 setAuthentication() 和 getAuthentication() 方法来存储和检索用户详细信息。

接下来,让我们讨论一下我们将用于应用程序的三个自定义实现。

表单登录

当我们将 Spring Security 添加到现有的 Spring 应用程序时,它会添加一个登录表单并设置一个虚拟用户。这是 Spring Security 的自动配置模式。在此模式下,它还设置了默认过滤器、身份验证管理器、身份验证提供程序等。此设置是内存中身份验证设置。我们可以覆盖此自动配置以设置我们自己的用户和身份验证过程。我们还可以设置自定义登录方法,例如自定义登录表单。Spring Security 只需要了解登录表单的详细信息,例如登录表单的 URI、登录处理 URL 等。然后,它将为应用程序呈现我们的登录表单,并执行身份验证过程以及其他提供的配置或 Spring 自己的实现。

自定义表单设置只需要遵守某些规则才能与 Spring Security 集成。我们需要有一个用户名参数和一个密码参数,并且参数名称应为“username”和“password”,因为这些是默认名称。如果我们在自定义中使用我们自己的参数名称来表示这些字段,则必须使用 usernameParameter() 和 passwordParameter() 方法通知 Spring Security 这些更改。类似地,对于我们对登录表单或表单登录方法所做的每个更改,我们都必须使用适当的方法通知 Spring Security 这些更改,以便它可以将它们与身份验证过程集成。

广告

© . All rights reserved.