SpringSecurity中文文档(Servlet Authorize HttpServletRequests)

news2024/9/22 19:27:22

Authorize HttpServletRequests

SpringSecurity 允许您在请求级别对授权进行建模。例如,对于 Spring Security,可以说/admin 下的所有页面都需要一个权限,而其他所有页面只需要身份验证。

默认情况下,SpringSecurity 要求对每个请求进行身份验证。也就是说,任何时候使用 HttpSecurity 实例,都需要声明授权规则。

无论何时有 HttpSecurity 实例,您至少应该这样做:

Use authorizeHttpRequests

http
    .authorizeHttpRequests((authorize) -> authorize
        .anyRequest().authenticated()
    )

这告诉 Spring Security,应用程序中的任何端点都需要至少对安全上下文进行身份验证才能允许它。

在许多情况下,您的授权规则将比这更复杂,因此请考虑以下用例:

  • 我有一个使用 AuthorizeRequest 的应用程序,我想将它迁移到 AuthorizeHttpRequest(I have an app that uses authorizeRequests and I want to migrate it to authorizeHttpRequests)
  • 我想了解 AuthorizationFilter 组件是如何工作的(I want to understand how the AuthorizationFilter components work)
  • 我希望根据模式匹配请求,特别是正则表达式(I want to match requests based on a pattern; specifically regex)
  • 我想匹配请求,并将 SpringMVC 映射到默认 servlet 之外的其他内容(I want to match request, and I map Spring MVC to something other than the default servlet)
  • I want to authorize requests
  • 希望以编程方式匹配请求(I want to match a request programmatically)
  • 我想以编程方式授权一个请求(I want to authorize a request programmatically)
  • 我要将请求授权委托给策略代理(I want to delegate request authorization to a policy agent)

Understanding How Request Authorization Components Work

本节通过深入研究基于 Servlet 的应用程序中的请求级授权如何工作,构建在 Servlet 体系结构和实现的基础上。

authorizationfilter

  • number 1 首先,AuthorizationFilter 构建了一个 Supplier,用于从 SecurityContextHolder 检索 Authentication。(First, the AuthorizationFilter constructs a Supplier that retrieves an Authentication from the SecurityContextHolder.)
  • number 2 第二,它将 Supplier 和 HttpServletRequest 传递给 AuthorizationManager。AuthorizationManager 将请求与 authorizeHttpRequests 中的模式进行匹配,并运行相应的规则。
    • number 3 如果授权被拒绝,将发布一个 AuthorizationDeniedEvent,并抛出一个 AccessDeniedException。在这种情况下,ExceptionTranslationFilter 将处理 AccessDeniedException。
    • number 4如果授予访问权限,则发布 AuthorizationGrantedEvent,AuthorizationFilter 继续使用 FilterChain,它允许应用程序正常处理。

AuthorizationFilter Is Last By Default

AuthorizationFilter 默认是 Spring Security 过滤器链中的最后一个。这意味着 Spring Security 的认证过滤器、漏洞保护以及其他过滤器集成不需要授权。如果您在 AuthorizationFilter 之前添加自己的过滤器,它们也不需要授权;否则,它们将需要授权。

一个典型的场景是当您添加 Spring MVC 端点时。因为它们由 DispatcherServlet 执行,这发生在 AuthorizationFilter 之后,所以您的端点需要被包含在 authorizeHttpRequests 中才能被允许。

All Dispatches Are Authorized

AuthorizationFilter 不仅在每次请求时运行,而且在每次分发时都会运行。这意味着 REQUEST 分发需要授权,但 FORWARD、ERROR 和 INCLUDE 也是如此。

例如,Spring MVC 可以将请求转发到呈现 Thymeleaf 模板的视图解析器,如下所示:

@Controller
public class MyController {
    @GetMapping("/endpoint")
    public String endpoint() {
        return "endpoint";
    }
}

在这种情况下,授权发生两次; 一次用于授权/端点,一次用于转发到 Thymeleaf 以呈现“端点”模板。

因此,您可能希望允许所有 FORWARD 分派。

这个原则的另一个例子是 SpringBoot 如何处理错误。如果容器捕获到异常,则如下所示:

Sample Erroring Spring MVC Controller

@Controller
public class MyController {
    @GetMapping("/endpoint")
    public String endpoint() {
        throw new UnsupportedOperationException("unsupported");
    }
}

然后 Boot 会将其发送到 ERROR 调度。

在这种情况下,授权也会发生两次: 一次用于授权/端点,一次用于分派错误。

因此,您可能希望允许所有 ERROR 分派。

Authentication Lookup is Deferred

记住 AuthorizationManager API 使用 Supplier < Authentication > 。

当请求总是被允许或总是被拒绝时,这与 AuthorizeHttpRequest 有关。在这些情况下,不会查询身份验证,从而使请求速度更快。

Authorizing an Endpoint

通过在优先顺序中添加更多规则,可以将 Spring Security 配置为具有不同的规则。

如果您希望只有具有 USER 权限的最终用户才能访问该/端点,那么您可以这样做:

@Bean
public SecurityFilterChain web(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests((authorize) -> authorize
	    .requestMatchers("/endpoint").hasAuthority("USER")
            .anyRequest().authenticated()
        )
        // ...

    return http.build();
}

如您所见,声明可以分解为pattern/rule对。

AuthorizationFilter 按列出的顺序处理这些对,只将第一个匹配应用到请求上。这意味着,即使 /** 也会匹配 /endpoint,上述规则也不是问题。阅读上述规则的方式是:“如果请求是 /endpoint,则需要 USER 权限;否则,只需认证”。

SpringSecurity 支持多种模式和多种规则; 您还可以通过编程方式创建自己的模式和规则。

一旦授权,您可以使用 Security 的测试支持以下方式对其进行测试:

Test Endpoint Authorization

@WithMockUser(authorities="USER")
@Test
void endpointWhenUserAuthorityThenAuthorized() {
    this.mvc.perform(get("/endpoint"))
        .andExpect(status().isOk());
}

@WithMockUser
@Test
void endpointWhenNotUserAuthorityThenForbidden() {
    this.mvc.perform(get("/endpoint"))
        .andExpect(status().isForbidden());
}

@Test
void anyWhenUnauthenticatedThenUnauthorized() {
    this.mvc.perform(get("/any"))
        .andExpect(status().isUnauthorized());
}

Matching Requests

上面已经介绍了两种匹配请求的方法。

您看到的第一个是最简单的,即匹配任何请求。

第二种是通过 URI 模式进行匹配。Spring Security 支持两种用于 URI 模式匹配的语言: Ant (如上所示)和正则表达式。

Matching Using Ant

Ant 是 Spring Security 用来匹配请求的默认语言。

您可以使用它来匹配单个端点或目录,甚至可以捕获占位符以供以后使用。您还可以对其进行细化以匹配一组特定的 HTTP 方法。

假设您不希望匹配/endpoint 端点,而是希望匹配/resource 目录下的所有端点。在这种情况下,您可以执行以下操作:

Match with Ant

http
    .authorizeHttpRequests((authorize) -> authorize
        .requestMatchers("/resource/**").hasAuthority("USER")
        .anyRequest().authenticated()
    )

解读方法是“如果请求是/resource 或某个子目录,则需要 USER 权限; 否则,只需要身份验证”

您还可以从请求中提取路径值,如下所示:

Authorize and Extract

http
    .authorizeHttpRequests((authorize) -> authorize
        .requestMatchers("/resource/{name}").access(new WebExpressionAuthorizationManager("#name == authentication.name"))
        .anyRequest().authenticated()
    )

一旦授权,您可以使用 Security 的测试支持以下方式对其进行测试:

Test Directory Authorization

@WithMockUser(authorities="USER")
@Test
void endpointWhenUserAuthorityThenAuthorized() {
    this.mvc.perform(get("/endpoint/jon"))
        .andExpect(status().isOk());
}

@WithMockUser
@Test
void endpointWhenNotUserAuthorityThenForbidden() {
    this.mvc.perform(get("/endpoint/jon"))
        .andExpect(status().isForbidden());
}

@Test
void anyWhenUnauthenticatedThenUnauthorized() {
    this.mvc.perform(get("/any"))
        .andExpect(status().isUnauthorized());
}

SpringSecurity 只匹配路径。如果要匹配查询参数,则需要一个自定义请求匹配器。

Matching Using Regular Expressions

SpringSecurity 支持将请求与正则表达式匹配。如果您想在子目录上应用比 * * 更严格的匹配条件,这可能很方便。

例如,考虑一个包含用户名的路径和所有用户名必须是字母数字的规则。您可以使用 RegexRequestMatcher 来遵守此规则,如下所示:

http
    .authorizeHttpRequests((authorize) -> authorize
        .requestMatchers(RegexRequestMatcher.regexMatcher("/resource/[A-Za-z0-9]+")).hasAuthority("USER")
        .anyRequest().denyAll()
    )

Matching By Http Method

还可以通过 HTTP 方法匹配规则。有一个地方很方便,那就是通过授予的权限进行授权,比如授予读或写权限。

为了要求所有 GET 都具有读权限,并且所有 POST 都具有写权限,您可以这样做:

Match by HTTP Method

http
    .authorizeHttpRequests((authorize) -> authorize
        .requestMatchers(HttpMethod.GET).hasAuthority("read")
        .requestMatchers(HttpMethod.POST).hasAuthority("write")
        .anyRequest().denyAll()
    )

这些授权规则的内容应该是: “如果请求是 GET,则需要读权限; 否则,如果请求是 POST,则需要写权限; 否则,拒绝请求”

默认情况下拒绝请求是一种健康的安全实践,因为它将规则集转换为允许列表。

一旦授权,您可以使用 Security 的测试支持以下方式对其进行测试:

Test Http Method Authorization

@WithMockUser(authorities="read")
@Test
void getWhenReadAuthorityThenAuthorized() {
    this.mvc.perform(get("/any"))
        .andExpect(status().isOk());
}

@WithMockUser
@Test
void getWhenNoReadAuthorityThenForbidden() {
    this.mvc.perform(get("/any"))
        .andExpect(status().isForbidden());
}

@WithMockUser(authorities="write")
@Test
void postWhenWriteAuthorityThenAuthorized() {
    this.mvc.perform(post("/any").with(csrf()))
        .andExpect(status().isOk());
}

@WithMockUser(authorities="read")
@Test
void postWhenNoWriteAuthorityThenForbidden() {
    this.mvc.perform(get("/any").with(csrf()))
        .andExpect(status().isForbidden());
}

Matching By Dispatcher Type

XML 当前不支持此特性

如前所述,SpringSecurity 默认授权所有调度程序类型。而且,即使在 REQUEST 分派上建立的安全上下文将传递给后续分派,微妙的不匹配有时也会导致意外的 AccessDeniedException。

为了解决这个问题,您可以配置 Spring Security Java 配置,以允许 FORWARD 和 ERROR 等调度程序类型,如下所示:

http
    .authorizeHttpRequests((authorize) -> authorize
        .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
        .requestMatchers("/endpoint").permitAll()
        .anyRequest().denyAll()
    )

Using an MvcRequestMatcher

一般来说,可以像上面演示的那样使用 requestMatcher (String)。

但是,如果将 SpringMVC 映射到不同的 servlet 路径,则需要在安全配置中考虑这一点。

例如,如果 Spring MVC 被映射到/Spring-MVC 而不是/(默认值) ,那么您可能有一个想要授权的端点,比如/Spring-MVC/my/controller。

您需要使用 MvcRequestMatcher 在配置中分割 servlet 路径和控制器路径,如下所示:

Example 2. Match by MvcRequestMatcher

@Bean
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
	return new MvcRequestMatcher.Builder(introspector).servletPath("/spring-mvc");
}

@Bean
SecurityFilterChain appEndpoints(HttpSecurity http, MvcRequestMatcher.Builder mvc) {
	http
        .authorizeHttpRequests((authorize) -> authorize
            .requestMatchers(mvc.pattern("/my/controller/**")).hasAuthority("controller")
            .anyRequest().authenticated()
        );

	return http.build();
}

这种需要至少可以通过两种不同的方式产生:

  • 如果使用 spring.mvc.servlet.path Boot 属性将默认路径(/)更改为其他内容
  • 如果您注册了多个 Spring MVC DispatcherServlet (因此要求其中一个不是默认路径)

Using a Custom Matcher

XML 当前不支持此特性

在 Java 配置中,您可以创建自己的 RequestMatcher 并将其提供给 DSL,如下所示:

Example 3. Authorize by Dispatcher Type

RequestMatcher printview = (request) -> request.getParameter("print") != null;
http
    .authorizeHttpRequests((authorize) -> authorize
        .requestMatchers(printview).hasAuthority("print")
        .anyRequest().authenticated()
    )

一旦授权,您可以使用 Security 的测试支持以下方式对其进行测试:

@WithMockUser(authorities="print")
@Test
void printWhenPrintAuthorityThenAuthorized() {
    this.mvc.perform(get("/any?print"))
        .andExpect(status().isOk());
}

@WithMockUser
@Test
void printWhenNoPrintAuthorityThenForbidden() {
    this.mvc.perform(get("/any?print"))
        .andExpect(status().isForbidden());
}

Authorizing Requests

一旦匹配了一个请求,您可以通过几种方式对其进行授权,如 permitAll、 denyAll 和 hasAuthority。

作为一个快速总结,以下是 DSL 中内置的授权规则:

  • PermitAll-请求不需要授权,是一个公共端点; 请注意,在这种情况下,永远不会从会话检索 Authentication
  • DenyAll-在任何情况下都不允许请求; 请注意,在这种情况下,永远不会从会话检索 Authentication
  • HasAuthority ——该请求要求 Authentication 具有与给定值匹配的 GrantedAuthority
  • HasRole-hasAuthority 的一个快捷方式,它将 ROLE _ 或其他配置为默认前缀的内容作为前缀
  • HasAnyAuthority ——该请求要求 Authentication 具有与任何给定值匹配的 GrantedAuthority
  • HasAnyrole-hasAnyAuthority 的一个快捷方式,它将 ROLE _ 或任何被配置为默认前缀的东西作为前缀
  • Access-请求使用此自定义 AuthorizationManager 来确定访问权限

现在已经了解了模式、规则以及如何将它们配对在一起,您应该能够理解在这个更复杂的示例中发生了什么:

import static jakarta.servlet.DispatcherType.*;

import static org.springframework.security.authorization.AuthorizationManagers.allOf;
import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasAuthority;
import static org.springframework.security.authorization.AuthorityAuthorizationManager.hasRole;

@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
	http
		// ...
		.authorizeHttpRequests(authorize -> authorize                                  (1)
            .dispatcherTypeMatchers(FORWARD, ERROR).permitAll() (2)
			.requestMatchers("/static/**", "/signup", "/about").permitAll()         (3)
			.requestMatchers("/admin/**").hasRole("ADMIN")                             (4)
			.requestMatchers("/db/**").access(allOf(hasAuthority("db"), hasRole("ADMIN")))   (5)
			.anyRequest().denyAll()                                                (6)
		);

	return http.build();
}
  1. 指定了多个授权规则。每个规则按其声明的顺序进行考虑。
  2. 分派 FORWARD 和 ERROR 允许 Spring MVC 呈现视图,Spring Boot 呈现错误
  3. 我们指定了任何用户都可以访问的多个 URL 模式。具体来说,如果 URL 以“/static/”、等于“/signup”或等于“/about”开头,则任何用户都可以访问请求。
  4. 任何以“/admin/”开头的 URL 将仅限于具有“ ROLE _ ADMIN”角色的用户。您会注意到,由于我们正在调用 hasRole 方法,因此不需要指定“ ROLE _”前缀。
  5. 任何以 “/db/” 开头的 URL 都需要用户同时拥有 “db” 权限以及 “ROLE_ADMIN” 角色。您会注意到,由于我们使用了 hasRole 表达式,因此不需要指定 “ROLE_” 前缀。
  6. 任何尚未匹配的 URL 都将被拒绝访问。如果您不想意外地忘记更新授权规则,那么这是一个很好的策略。

Expressing Authorization with SpEL

虽然建议使用具体的 AuthorizationManager,但是在某些情况下需要使用表达式,比如使用 < stop-url > 或 JSP Taglibs。出于这个原因,本节将重点介绍来自这些域的示例。

既然如此,让我们更深入地讨论一下 Spring Security 的 Web 安全授权 SpEL API。

Spring Security 将其所有的授权字段和方法封装在一个集合的根对象中。最通用的根对象称为 SecurityExpressionRoot,它是 WebSecurityExpressionRoot 的基础。当准备评估授权表达式时,Spring Security 将这个根对象提供给 StandardEvaluationContext。

Using Authorization Expression Fields and Methods

它提供的第一件事是增强了 SpEL 表达式的授权字段和方法集。以下是最常用方法的简要概述:

  • permitAll - 请求不需要任何授权即可调用;注意,在这种情况下,Authentication 从未从会话中检索

  • denyAll - 请求在任何情况下都不被允许;注意,在这种情况下,Authentication 从未从会话中检索

  • hasAuthority - 请求需要 Authentication 具有与给定值匹配的 GrantedAuthority

  • hasRole - hasAuthority 的快捷方式,默认前缀为 ROLE_ 或配置的默认前缀

  • hasAnyAuthority - 请求需要 Authentication 具有与给定值中的任何一个匹配的 GrantedAuthority

  • hasAnyRole - hasAnyAuthority 的快捷方式,默认前缀为 ROLE_ 或配置的默认前缀

  • HasPermission-一个连接到您的 Permisonevalator 实例的钩子,用于执行对象级授权

以下是一些最常见的领域:

  • authentication - 与本方法调用相关联的 Authentication 实例

  • principal - 与本方法调用相关联的 Authentication#getPrincipal

现在已经了解了模式、规则以及如何将它们配对在一起,您应该能够理解在这个更复杂的示例中发生了什么:

Authorize Requests Using SpEL

<http>
    <intercept-url pattern="/static/**" access="permitAll"/>1<intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/>2<intercept-url pattern="/db/**" access="hasAuthority('db') and hasRole('ADMIN')"/>3<intercept-url pattern="/**" access="denyAll"/>4</http>
  1. 我们指定了一个任何用户都可以访问的 URL 模式。具体来说,如果 URL 以“/static/”开头,任何用户都可以访问请求。
  2. 任何以“/admin/”开头的 URL 将仅限于具有“ ROLE _ ADMIN”角色的用户。您会注意到,由于我们正在调用 hasRole 方法,因此不需要指定“ ROLE _”前缀。
  3. 任何以 “/db/” 开头的 URL 都需要用户同时拥有 “db” 权限以及 “ROLE_ADMIN” 角色。您会注意到,由于我们使用了 hasRole 表达式,因此不需要指定 “ROLE_” 前缀。
  4. 任何尚未匹配的 URL 都将被拒绝访问。如果您不想意外地忘记更新授权规则,那么这是一个很好的策略。

Using Path Parameters

此外,Spring Security 提供了一种发现路径参数的机制,因此也可以在 SpEL 表达式中访问这些参数。

例如,您可以通过以下方式访问 SpEL 表达式中的路径参数:

Authorize Request using SpEL path variable

<http>
    <intercept-url pattern="/resource/{name}" access="#name == authentication.name"/>
    <intercept-url pattern="/**" access="authenticated"/>
</http>

这个表达式引用/resource/之后的 path 变量,并要求它等于 Authentication # getName。

Use an Authorization Database, Policy Agent, or Other Service

如果希望将 Spring Security 配置为使用单独的服务进行授权,可以创建自己的 AuthorizationManager 并将其与 anyRequest 匹配。

首先,您的 AuthorizationManager 可能看起来像这样:

Open Policy Agent Authorization Manager

@Component
public final class OpenPolicyAgentAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {
    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext context) {
        // make request to Open Policy Agent
    }
}

然后,您可以通过以下方式将其连接到 Spring Security:

Any Request Goes to Remote Service

@Bean
SecurityFilterChain web(HttpSecurity http, AuthorizationManager<RequestAuthorizationContext> authz) throws Exception {
	http
		// ...
		.authorizeHttpRequests((authorize) -> authorize
            .anyRequest().access(authz)
		);

	return http.build();
}

Favor permitAll over ignoring

当您拥有静态资源时,很容易将筛选器链配置为忽略这些值。一个更安全的方法是允许他们使用 permitAll like so:

Example 4. Permit Static Resources

http
    .authorizeHttpRequests((authorize) -> authorize
        .requestMatchers("/css/**").permitAll()
        .anyRequest().authenticated()
    )

它更加安全,因为即使使用静态资源,编写安全头文件也很重要,如果忽略请求,Spring Security 就无法做到这一点。

在过去,这带来了性能折衷,因为 Spring Security 在每次请求时都会咨询会话。但是,从 SpringSecurity6开始,除非授权规则要求,否则不再 ping 会话。由于现在已经解决了性能影响问题,SpringSecurity 建议对所有请求至少使用 permitAll。

Migrating from authorizeRequests

AuthorizationFilter 为 HttpServletRequest 提供授权。它作为安全筛选器之一插入到 FilterChainProxy 中。

您可以在声明 SecurityFilterChain 时覆盖默认值:

@Bean
SecurityFilterChain web(HttpSecurity http) throws AuthenticationException {
    http
        .authorizeHttpRequests((authorize) -> authorize
            .anyRequest().authenticated();
        )
        // ...

    return http.build();
}

这在若干方面改进了 AuthorizeRequest:

  • 使用简化的 AuthorizationManager API 而不是元数据源、配置属性、决策管理器和投票者metadata sources, config attributes, decision managers, and voters.。这简化了重用和自定义。
  • 延迟 Authentication 查找。而不是为每个请求都查找 Authentication,只有在需要授权决策时才会查找。
  • 支持基于 Bean 的配置。

如果使用 AuthorizeHttpRequest 代替 AuthorizeRequest,则使用 AuthorizationFilter 代替 FilterSecurityInterceptor。

Migrating Expressions

在可能的情况下,建议使用类型安全授权管理器而不是 SpEL。对于 Java 配置,WebExpressionAuthorizationManager 可用于帮助迁移遗留的 SpEL。

要使用 WebExpressionAuthorizationManager,您可以使用试图迁移的表达式构造一个表达式,如下所示:

.requestMatchers("/test/**").access(new WebExpressionAuthorizationManager("hasRole('ADMIN') && hasRole('USER')"))

如果您在表达式中引用一个 bean,例如:@webSecurity.check(authentication, request),建议您直接调用 bean,它看起来会像这样:

.requestMatchers("/test/**").access((authentication, context) ->
    new AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest())))

对于包含 bean 引用和其他表达式的复杂指令,建议更改这些指令以实现 AuthorizationManager,并通过调用.access(AuthorizationManager).

如果不能这样做,可以使用 bean 解析器配置 DefaultHttpSecurityExpressionHandler,并将其提供给 WebExpressionAuthorizationManager # setExpressionHandler。

Security Matchers

RequestMatcher 接口用于确定请求是否与给定的规则匹配。我们使用 securityMatchers 来确定给定的 HttpSecurity 是否应该应用于给定的请求。同样,我们可以使用 requestMatchers 来确定应该应用于给定请求的授权规则。请看以下示例:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		http
			.securityMatcher("/api/**")
			.authorizeHttpRequests(authorize -> authorize
				.requestMatchers("/user/**").hasRole("USER")
				.requestMatchers("/admin/**").hasRole("ADMIN")
				.anyRequest().authenticated()
			)
			.formLogin(withDefaults());
		return http.build();
	}
}
  1. 将 HttpSecurity 配置为仅应用于以/api/开头的 URL
  2. 允许具有 USER 角色的用户访问以 /user/ 开头的 URL
  3. 允许具有 ADMIN 角色的用户访问以/admin/开头的 URL
  4. 任何其他与上述规则不匹配的请求都将需要身份验证

SecurityMatcher (s)和 requestMatcher (s)方法将决定哪个 RequestMatcher 实现最适合您的应用程序: 如果 Spring MVC 在类路径中,那么将使用 MvcRequestMatcher,否则将使用 AntPathRequestMatcher。您可以在这里了解更多关于 Spring MVC 集成的信息。

如果您想使用一个特定的 RequestMatcher,只需将一个实现传递给 securityMatcher 和/或 requestMatcher 方法:

import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; (1)
import static org.springframework.security.web.util.matcher.RegexRequestMatcher.regexMatcher;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		http
			.securityMatcher(antMatcher("/api/**"))                              (2)
			.authorizeHttpRequests(authorize -> authorize
				.requestMatchers(antMatcher("/user/**")).hasRole("USER")         (3)
				.requestMatchers(regexMatcher("/admin/.*")).hasRole("ADMIN")     (4)
				.requestMatchers(new MyCustomRequestMatcher()).hasRole("SUPERVISOR")     (5)
				.anyRequest().authenticated()
			)
			.formLogin(withDefaults());
		return http.build();
	}
}

public class MyCustomRequestMatcher implements RequestMatcher {

    @Override
    public boolean matches(HttpServletRequest request) {
        // ...
    }
}
  1. 从 AntPathRequestMatcher 和 RegexRequestMatcher 导入静态工厂方法以创建 RequestMatcher 实例。
  2. 使用 AntPathRequestMatcher 将 HttpSecurity 配置为仅应用于以/api/开头的 URL
  3. 允许使用 AntPathRequestMatcher 访问以/USER/开头的 URL 到具有 USER 角色的用户
  4. 允许使用 RegexRequestMatcher 对具有 ADMIN 角色的用户访问以/ADMIN/开头的 URL
  5. 允许使用自定义 RequestMatcher 访问与具有 SUPERVISOR 角色的用户匹配的 MyCustomRequestMatcher 的 URL

Further Reading

既然已经保护了应用程序的请求,那么就考虑保护它的方法。您还可以进一步阅读关于测试应用程序或将 Spring Security 与应用程序的其他方面(如数据层或跟踪和度量)集成的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1906806.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java套红:指定位置合并文档-NiceXWPFDocument

需求&#xff1a;做个公文系统&#xff0c;需要将正文文档在某个节点点击套红按钮&#xff0c;实现文档套红 试了很多方法&#xff0c;大多数网上能查到但是实际代码不能找到关键方法&#xff0c;可能是跟包的版本有关系&#xff0c;下面记录能用的这个。 一&#xff1a;添加依…

《C++20设计模式》命令模式思考

文章目录 一、前言二、分析 拆解1、经典命令模式2、撤销操作3、关于Invoker类 三、实现 一、前言 哎&#xff01;只要是书上写的和经典设计模式不同&#xff0c;我就会很伤脑筋。&#x1f629; 命令模式到底是干什么的&#xff1f; 答&#xff1a;命令的发送者和接收者完全解…

“一稿多投”是学术不端,还是作者的合法权利?

【SciencePub学术】“一稿多投”一直被认为是不端的行为&#xff0c;但这个“规矩”是在纸质时代信息沟通不畅的情况下制定的&#xff0c;近年来有关取消这一观念的声音已振聋发聩&#xff01; 詹启智的《一稿多投是著作权人依法享有的合法权利一一兼论一稿多发后果的规制》一文…

SpringBoot项目——送水管理系统

1、导入坐标 坐标作用pagehelper-spring-boot-startermybatis分页插件spring-boot-starter-thymeleafJSP模板引擎mybatis-spring-boot-startermybatisspring-boot-starter-webwebspring-boot-starter-testtestlombok不需要再写getter、setter或equals方法&#xff0c;只要有一…

建立有效的DNS性能检测机制

今天来分享如何建立有效的DNS性能监测机制&#xff0c;实时或定期监测关键指标。 一、建立DNS性能监测机制 &#xff08;一&#xff09;选择合适的监测工具 市场上有多种DNS性能监测工具可供选择&#xff0c;如IP数据云DNS检测功能。其具备强大的功能&#xff0c;能够针对多种…

简过网:快来看看你的专业能考哪个类型的事业单位?

你的专业能考哪个类型的事业单位&#xff0c;你知道吗&#xff1f;想考事业单位的姐妹&#xff0c;一定要在备考之前&#xff0c;查清楚你的专业适不适合考事业单位、考哪类事业编以及能报考哪些岗位&#xff1f;这个才能上岸的几率更高一些&#xff01; 事业单位有5类岗位&am…

Java动态执行jar包中类的方法

动态加载执行jar包&#xff0c;在实际开发中经常会需要用到&#xff0c;尤其涉及平台和业务的关系的时候&#xff0c;业务逻辑部分可以独立出去交给业务方管理&#xff0c;业务方只需要提供jar包&#xff0c;就能在平台上运行。 结论 通过反射可以实现动态调用jar包中的类的方…

免费可商用的Navicat Premium Lite要不要用?小心收到律丝函!

作者公众号&#xff1a;霸王龙的日常 专注数据库&#xff0c;分享实用的项目实战经验。 上周五写了一篇关于Navicat Premium Lite的文章&#xff0c;有网友去官网下载&#xff0c;反馈当前官网Navicat Premium Lite简介和我之前文章中的介绍的有出入。 我赶紧打开网站看了下Na…

修改CentOS7.9跟Unbantu24的ip地址

修改CentOS的IP地址 ip addr 查看IP地址 cd /etc/sysconfig/network-scripts ls vi ifcfg-ens33修改ip地址跟干网关地址 TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no" BOOTPROTO"static" DEFROUTE"yes" IPV4_FA…

排序 -- 手撕归并排序(递归和非递归写法)

一、基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有…

掌上教务系统-计算机毕业设计源码84604

摘要 在数字化教育日益成为主流的今天&#xff0c;教务管理系统的智能化和便捷性显得尤为重要。为满足学校、教师、学生及家长对教务管理的高效需求&#xff0c;我们基于Spring Boot框架设计并实现了一款掌上教务系统。该系统不仅具备课程分类管理功能&#xff0c;使各类课程信…

软件架构之开发方法

软件架构之开发方法 第6章&#xff1a;开发方法6.1 软件生命周期6.2 软件开发模型6.2.1 瀑布模型6.2.2 演化模型6.2.3 螺旋模型6.2.4 增量模型6.2.5 构件组装模型 6.3 统一过程6.4 敏捷方法6.4.1 极限编程6.4.2 特征驱动开发6.4.3 Scrum6.4.4 水晶方法6.4.5 其他敏捷方法 6.5 软…

《梦醒蝶飞:释放Excel函数与公式的力量》9.5 IRR函数

9.5 IRR函数 IRR函数是Excel中用于计算内部收益率&#xff08;Internal Rate of Return, IRR&#xff09;的函数。内部收益率是评估投资项目盈利性的重要指标&#xff0c;它表示使投资项目的净现值&#xff08;NPV&#xff09;为零的折现率。 9.5.1 函数简介 IRR函数通过一系…

微软开源GraphRAG的使用教程-使用自定义数据测试GraphRAG

微软在今年4月份的时候提出了GraphRAG的概念&#xff0c;然后在上周开源了GraphRAG,Github链接见https://github.com/microsoft/graphrag,截止当前&#xff0c;已有6900Star。 安装教程 官方推荐使用Python3.10-3.12版本&#xff0c;我使用Python3.10版本安装时&#xff0c;在…

Java:String 类

文章目录 一、概念二、创建字符串三、字符串长度四、连接字符串五、比较字符串 一、概念 字符串广泛应用 在 Java 编程中&#xff0c;在 Java 中字符串属于对象&#xff0c;Java 提供了 String 类来创建和操作字符串。 二、创建字符串 创建字符串最简单的方式如下: // 直接创…

利用Python进行数据分析PDF下载经典数据分享推荐

本书由Python pandas项目创始人Wes McKinney亲笔撰写&#xff0c;详细介绍利用Python进行操作、处理、清洗和规整数据等方面的具体细节和基本要点。第2版针对Python 3.6进行全面修订和更新&#xff0c;涵盖新版的pandas、NumPy、IPython和Jupyter&#xff0c;并增加大量实际案例…

什么是Common Flash Interface

目录 1. CFI概述 2. CFI的使用小结 3. CFI在车规MCU里有用吗 在看关于ifx的标准flash驱动配置时&#xff0c;无意中瞄到一个注灰的选项&#xff1a; Try to use CFI information to detect Flash Type 之前讲过CFI这个标准&#xff0c;但为何在IFX memtool工具里注灰&#x…

opencv实现人脸检测功能----20240704

opencv实现人脸检测 早在 2017 年 8 月,OpenCV 3.3 正式发布,带来了高度改进的“深度神经网络”(dnn)模块。 该模块支持多种深度学习框架,包括 Caffe、TensorFlow 和 Torch/PyTorch。OpenCV 的官方版本中包含了一个更准确、基于深度学习的人脸检测器, 链接:基于深度学习…

基于springboot+vue+uniapp的贵工程寝室快修小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

人员定位系统的功能,你知道多少呢?

在此前的文章中&#xff0c;说到了人员定位系统用于化工厂定位这一用途来完善工厂管理&#xff0c;但同时&#xff0c;基于人员定位系统的强大功能&#xff0c;该系统的应用范围也要宽范的多&#xff0c;那么&#xff0c;本篇文章就来为大家介绍一下吧。 人员定位系统的功能简介…