SpringSecurity中文文档(Servlet Authorize HttpServletRequests)

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> {@Overridepublic 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 {@Beanpublic 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 {@Beanpublic 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 {@Overridepublic 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.mzph.cn/web/43816.shtml

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

相关文章

Umi.js 项目中使用 Web Worker

1.配置 Umi.js 在 Umi.js 中&#xff0c;需要通过配置来扩展 Webpack 的功能。在项目根目录下修改 config/config.ts 文件&#xff1a; export default defineConfig({chainWebpack(config) {config.module.rule(worker).test(/\.worker\.ts$/).use(worker-loader).loader(wo…

C语言之指针的奥秘(二)

一、数组名的理解 int arr[10]{1,2,3,4,5,6,7,8,9,10}; int *p&arr[0]; 这里使用 &arr[0] 的⽅式拿到了数组第⼀个元素的地址&#xff0c;但是其实数组名本来就是地址&#xff0c;而且是数组首元素的地址。如下&#xff1a; 我们发现数组名和数组⾸元素的地址打印出…

重要文件放u盘还是硬盘?硬盘和u盘哪个适合长期存储

在数字时代&#xff0c;我们每天都会处理大量的文件。其中&#xff0c;不乏一些对我们而言至关重要的文件&#xff0c;如家庭照片、工作文档、财务记录等。面对这些重要文件的存储问题&#xff0c;我们通常会面临&#xff1a;“重要文件放U盘还是硬盘”、“硬盘和U盘哪个适合长…

Vue2打包部署后动态修改后端接口地址的解决方法

文章目录 前言一、背景二、解决方法1.在public文件夹下创建config文件夹&#xff0c;并创建config.js文件2.编写config.js内容3.在index.html中加载config.js4.在封装axios工具类的js中修改配置 总结 前言 本篇文章将介绍使用Vue2开发前后端分离项目时&#xff0c;前端打包部署…

系统架构师考点--系统安全

大家好。今天我来总结一下系统安全相关的考点&#xff0c;这类考点每年都会考到&#xff0c;一般是在上午场客观题&#xff0c;占2-4分。 一、信息安全基础知识 信息安全包括5个基本要素&#xff1a;机密性、完整性、可用性、可控性与可审查性 (1)机密性&#xff1a;确保信息…

Navicat导入sql文件

文章目录 Navicat导入SQL文件&#xff0c;使用默认导入&#xff0c;不做任何修改报错尝试一修改运行时的选择 尝试二修改my.ini的配置文件 Navicat导入SQL文件&#xff0c;使用默认导入&#xff0c;不做任何修改报错 尝试一 修改运行时的选择 取消勾选 ‘每个运行中运行多重查…

3,区块链加密(react+区块链实战)

3&#xff0c;区块链加密&#xff08;react区块链实战&#xff09; 3.1 哈希3.2 pow-pos-dpos3.3非对称加密&#xff08;1&#xff09;对称加密AES&#xff08;2&#xff09;非对称加密RSA 3.4 拜占庭将军3.5 P2P网络3.6 区块链 3.1 哈希 密码学&#xff0c;区块链的技术名词 …

【Git的基本操作】版本回退 | 撤销修改的三种情况 | 删除文件

目录 5.版本回退 5.1选项hard&后悔药 5.2后悔药&commit id 5.3版本回退的原理 6.撤销修改 6.1情况一 6.2情况二 6.3情况三 ​7.删除文件 Git重要能力之一马&#xff0c;版本回退功能。Git是版本控制系统&#xff0c;能够管理文件历史版本。本篇以ReadMe文件为…

神器!3个免费PPT成品网站推荐+3款AIPPT工具盘点!

熬夜加班做PPT却没有头绪&#xff1f;别再自己憋着想了&#xff01;现在凡事主打一个“抄作业”&#xff0c;想做ppt却没想法&#xff0c;可以去到ppt成品网站搜集PPT模板&#xff0c;或是使用时下流行的AI生成PPT工具&#xff0c;只需输入PPT主题&#xff0c;即可快速生成一份…

全网最详细的CRC讲解即计算

CRC 循环冗余码&#xff08;Cyclic Redundancy Code&#xff0c; CRC&#xff09;是一种用于校验通信链路上数字传输准确性的计算方法&#xff08;通过某种数学运算来建立数据位和校验位(CRC)的约定关系的&#xff09;。它是利用除法以及余数的原理来作错误侦测。 发送方: 使用…

客户关系管理怎么做?这4个工具一定要会用!

在商海浮沉中&#xff0c;每一位企业家和销售经理都深知&#xff0c;客户是企业生存与发展的基石。但如何有效管理这些宝贵的资源&#xff0c;让每一次互动都成为加深关系、促进成交的契机&#xff0c;却是一门艺术加科学的结合体。今天&#xff0c;咱们就来聊聊客户关系管理&a…

3SRB5016-ASEMI逆变箱专用3SRB5016

编辑&#xff1a;ll 3SRB5016-ASEMI逆变箱专用3SRB5016 型号&#xff1a;3SRB5016 品牌&#xff1a;ASEMI 封装&#xff1a;SGBJ-5 批号&#xff1a;2024 现货&#xff1a;50000 最大重复峰值反向电压&#xff1a;1600V 最大正向平均整流电流(Vdss)&#xff1a;50A 功…

Kodcloud可道云安装与一键发布上线实现远程访问详细教程

文章目录 1.前言2. Kodcloud网站搭建2.1. Kodcloud下载和安装2.2 Kodcloud网页测试 3. cpolar内网穿透的安装和注册4. 本地网页发布4.1 Cpolar云端设置4.2 Cpolar本地设置 5. 公网访问测试6.结语 1.前言 本文主要为大家介绍一款国人自研的在线Web文件管理器可道云&#xff0c;…

唐刘:当 SaaS 爱上 TiDB(一)- 行业挑战与 TiDB 的应对之道

导读 在 TiDB 8.1 发布后&#xff0c;TiDB 展现了强大的支持 SaaS 业务的能力&#xff0c;成为 SaaS 业务数据库的优先选择之一。 本文为“当 SaaS 爱上 TiDB”系列文章的第一篇&#xff0c;系列文章将从技术原理和真实用户体验两个角度深入探讨 TiDB 在 SaaS 业务中的表现&a…

太速科技-3U VPX飞腾处理器刀片计算机

3U VPX飞腾处理器刀片计算机 一 、产品概述 该产品是一款基于国产飞腾FT2000 4核或腾锐D2000 8核的高性能3U VPX刀片式计算机。产品提供了4个x4 PCIe 3.0总线接口&#xff0c;同时可配置为1个x16或2个x8 PCIe3.0接口&#xff0c;因此具有很强的扩展性&#xff0c;极大…

agents 分类

一、分类 自动agent、半自动agent、领域、自定义sop和支持人为干预的agent。 先泼个冷水&#xff0c;目前这些agent项目都是实验品&#xff0c;发展还没有做知识库问答相关开源项目那么成熟&#xff0c; 二、全自动agent autoGPT、loopGPT、babyAGI 全自动agent就是人类不可…

实例演示Kafka-Stream消息流式处理流程及原理

以下结合案例&#xff1a;统计消息中单词出现次数&#xff0c;来测试并说明kafka消息流式处理的执行流程 Maven依赖 <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-streams</artifactId><exclusio…

Java中的LinkedList(链表)(如果想知道Java中有关LinkedList的知识点,那么只看这一篇就足够了!)

前言&#xff1a;在Java编程语言中&#xff0c;Java集合框架提供了一组丰富的数据结构&#xff0c;以满足各种应用需求。其中&#xff0c;LinkedList作为一种常用的数据结构&#xff0c;具有独特的优势和广泛的应用场景。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内…

linux radix-tree 基数树实现详解

radix tree&#xff0c;又称做基数树&#xff0c;是一种适合于构建key(index)与value(item)相关联的数据结构。内核中使用非常广泛。本文主要聚焦linux内核基数树的代码实现,大量注释过的代码。 radix-tree组织结构如下: 1、数据结构 /** The bottom two bits of the slot de…

IDEA阿里云OSS实现文件上传·解决苍穹外卖图片回显

简单交代配置阿里云OSS的思路 1. 首先去阿里云开通一个OSS服务&#xff0c;配置好一个自己的Bucket 2. 在IDEA配置Bucket 3. 拷贝官网的OSS工具类代码 package com.sky.utils;import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSS…