# 授权 HttpServletRequestwithAuthorizationFilter 本节通过深入研究[授权](index.html#servlet-authorization)在基于 Servlet 的应用程序中的工作方式,构建了[Servlet Architecture and Implementation](../architecture.html#servlet-architecture)。 | |`AuthorizationFilter`取代[`FilterSecurityInterceptor`](authorize-requests.html# Servlet-authorization-filtersecurityinterceptor)。
要保持向后兼容,`FilterSecurityInterceptor`仍然是默认值。
本节讨论`AuthorizationFilter`如何工作以及如何覆盖默认配置。| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| [`AuthorizationFilter`](https://DOCS. Spring.io/ Spring-security/site/DOCS/5.6.2/api/org/springframework/security/web/access/intercept/intercept/authorizationfilter.html)为`HttpServletRequest`s 提供[授权](index.html#servlet-authorization)。它作为[安全过滤器](../architecture.html#servlet-security-filters)中的一个插入到[FilterchainProxy](../architecture.html#servlet-filterchainproxy)中。 声明`SecurityFilterChain`时,可以重写默认值。不要使用[`authorizeRequests`](# Servlet-authorize-requests-defaults),而是使用`authorizeHttpRequests`,就像这样: 例 1。使用 AuthorizeHttpRequests 爪哇 ``` @Bean SecurityFilterChain web(HttpSecurity http) throws AuthenticationException { http .authorizeHttpRequests((authorize) -> authorize .anyRequest().authenticated(); ) // ... return http.build(); } ``` 这在以下几个方面改进了`authorizeRequests`: 1. 使用简化的`AuthorizationManager`API,而不是元数据源、配置属性、决策管理器和投票者。这简化了重用和定制。 2. 延迟`Authentication`查找。而不是需要为每个请求查找身份验证,它只会在授权决策需要身份验证的请求中查找。 3. Bean-基于配置支持。 当使用`authorizeHttpRequests`而不是`authorizeRequests`时,则使用[`AuthorizationFilter`](https://DOCS. Spring.io/ Spring-security/site/DOCS/5.6.2/api/org/springframework/security/web/access/intercept/Authorizationfilter.html)代替[<<](authority-requests.html# Servlet-authority-filtersecurityptor)。 ![授权过滤器](https://docs.spring.io/spring-security/reference/_images/servlet/authorization/authorizationfilter.png) 图 1。授权 HttpServletRequest * ![number 1](https://docs.spring.io/spring-security/reference/_images/icons/number_1.png)首先,`AuthorizationFilter`从[SecurityContextholder](../authentication/architecture.html#servlet-authentication-securitycontextholder)得到[认证](../authentication/architecture.html#servlet-authentication-authentication)。它将此包在`Supplier`中,以延迟查找。 * ![number 2](https://docs.spring.io/spring-security/reference/_images/icons/number_2.png)秒,`AuthorizationFilter`从`HttpServletRequest`、`FilterInvocation`、`和`FilterInvocation`传递给[`AuthorizationManager`]。 * ![number 4](https://docs.spring.io/spring-security/reference/_images/icons/number_4.png)如果拒绝授权,将抛出`AccessDeniedException`。在这种情况下,[`ExceptionTranslationFilter`](../architecture.html# Servlet-ExceptionTranslationFilter)处理`AccessDeniedException`。 * ![number 5](https://docs.spring.io/spring-security/reference/_images/icons/number_5.png)如果访问被授予,`AuthorizationFilter`继续使用[滤清链](../architecture.html#servlet-filters-review),这允许应用程序正常处理。 通过按优先级顺序添加更多规则,我们可以将安全性配置为具有不同的规则。 例 2。授权请求 爪哇 ``` @Bean SecurityFilterChain web(HttpSecurity http) throws Exception { http // ... .authorizeHttpRequests(authorize -> authorize (1) .mvcMatchers("/resources/**", "/signup", "/about").permitAll() (2) .mvcMatchers("/admin/**").hasRole("ADMIN") (3) .mvcMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") (4) .anyRequest().denyAll() (5) ); return http.build(); } ``` |**1**|指定了多个授权规则。
每个规则都按照它们被声明的顺序被考虑。| |-----|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |**2**|我们指定了任何用户都可以访问的多个 URL 模式。
具体来说,如果 URL 以“/resources/”开头,等于“/signup”或等于“/about”,则任何用户都可以访问请求。| |**3**|任何以“/admin/”开头的 URL 都将被限制为具有角色“role\_admin”的用户。
你将注意到,由于我们正在调用`hasRole`方法,因此我们不需要指定“role\_”前缀。| |**4**|任何以“/db/”开头的 URL 都要求用户同时具有“role\_admin”和“role\_DBA”。
你将注意到,由于我们使用的是`hasRole`表达式,因此我们不需要指定“role\_”前缀。| |**5**|任何尚未匹配的 URL 都将被拒绝访问。
如果你不想意外地忘记更新授权规则,这是一个很好的策略。| 你可以通过构建自己的[`RequestMatcherDelegatingAuthorizationManager`](architecture.html#authz-delegate-authorization-manager)来采用基于 Bean 的方法,如下所示: 例 3。配置 RequestMatcherDelegatingAuthorizationManager 爪哇 ``` @Bean SecurityFilterChain web(HttpSecurity http, AuthorizationManager access) throws AuthenticationException { http .authorizeHttpRequests((authorize) -> authorize .anyRequest().access(access) ) // ... return http.build(); } @Bean AuthorizationManager requestMatcherAuthorizationManager(HandlerMappingIntrospector introspector) { RequestMatcher permitAll = new AndRequestMatcher( new MvcRequestMatcher(introspector, "/resources/**"), new MvcRequestMatcher(introspector, "/signup"), new MvcRequestMatcher(introspector, "/about")); RequestMatcher admin = new MvcRequestMatcher(introspector, "/admin/**"); RequestMatcher db = new MvcRequestMatcher(introspector, "/db/**"); RequestMatcher any = AnyRequestMatcher.INSTANCE; AuthorizationManager manager = RequestMatcherDelegatingAuthorizationManager.builder() .add(permitAll, (context) -> new AuthorizationDecision(true)) .add(admin, AuthorityAuthorizationManager.hasRole("ADMIN")) .add(db, AuthorityAuthorizationManager.hasRole("DBA")) .add(any, new AuthenticatedAuthorizationManager()) .build(); return (context) -> manager.check(context.getRequest()); } ``` 你还可以为任何请求匹配器连接[你自己的自定义授权管理器](architecture.html#authz-custom-authorization-manager)。 下面是将自定义授权管理器映射到`my/authorized/endpoint`的示例: 例 4。自定义授权管理器 爪哇 ``` @Bean SecurityFilterChain web(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize) -> authorize .mvcMatchers("/my/authorized/endpoint").access(new CustomAuthorizationManager()); ) // ... return http.build(); } ``` 或者,你可以为所有请求提供它,如下所示: 例 5。所有请求的自定义授权管理器 爪哇 ``` @Bean SecurityFilterChain web(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize) -> authorize .anyRequest.access(new CustomAuthorizationManager()); ) // ... return http.build(); } ``` [授权体系结构](architecture.html)[使用 FilterSecurityInterceptor 授权 HTTP 请求](authorize-requests.html)