# 使用 FilterSecurityInterceptor 授权 HttpServletRequest

FilterSecurityInterceptor正在被[AuthorizationFilter]替换。
考虑使用它。

本节通过深入研究授权在基于 Servlet 的应用程序中的工作方式,构建了Servlet Architecture and Implementation

[FilterSecurityInterceptor](https://DOCS. Spring.io/ Spring-security/site/DOCS/5.6.2/api/org/springframework/security/web/access/intercept/filtersecurityinterceptor.html)为HttpServletRequests 提供授权。它作为安全过滤器中的一个插入到FilterchainProxy中。

过滤安全拦截器

图 1。授权 HttpServletRequest

  • number 1首先,FilterSecurityInterceptorSecurityContextholder得到一个认证

  • number 2第二,FilterSecurityInterceptorHttpServletRequestHttpServletResponseFilterChain中创建一个[FilterChain(https://DOCS. Spring.io/ Spring-security/site/site/DOCS/5.6.2/api/org/springframework/security/web/filterinvocation.html),并传递到HttpServletRequest中的HttpServletResponseFilterChain中。

  • number 3下一步,它将FilterInvocation传递到SecurityMetadataSource,得到ConfigAttributes。

  • number 4最后,它将AuthenticationFilterInvocationConfigAttributes 传递给 Xref: Servlet/授权。ADOC#authz-access-decision-managerAccessDecisionManager

    • number 5如果拒绝授权,将抛出AccessDeniedException。在这种情况下,[ExceptionTranslationFilter](../architecture.html# Servlet-ExceptionTranslationFilter)处理AccessDeniedException

    • number 6如果访问被授予,FilterSecurityInterceptor继续使用滤清链,这允许应用程序正常处理。

默认情况下, Spring Security 的授权将要求对所有请求进行身份验证。显式配置如下所示:

例 1。每个请求都必须经过验证。

爪哇

protected void configure(HttpSecurity http) throws Exception {
	http
		// ...
		.authorizeRequests(authorize -> authorize
			.anyRequest().authenticated()
		);
}

XML

<http>
	<!-- ... -->
	<intercept-url pattern="/**" access="authenticated"/>
</http>

Kotlin

fun configure(http: HttpSecurity) {
    http {
        // ...
        authorizeRequests {
            authorize(anyRequest, authenticated)
        }
    }
}

我们可以通过按优先级顺序添加更多规则来配置 Spring 安全性,使其具有不同的规则。

例 2。授权请求

爪哇

protected void configure(HttpSecurity http) throws Exception {
	http
		// ...
		.authorizeRequests(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)
		);
}

XML

<http> (1)
	<!-- ... -->
	(2)
	<intercept-url pattern="/resources/**" access="permitAll"/>
	<intercept-url pattern="/signup" access="permitAll"/>
	<intercept-url pattern="/about" access="permitAll"/>

	<intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/> (3)
	<intercept-url pattern="/db/**" access="hasRole('ADMIN') and hasRole('DBA')"/> (4)
	<intercept-url pattern="/**" access="denyAll"/> (5)
</http>

Kotlin

fun configure(http: HttpSecurity) {
   http {
        authorizeRequests { (1)
            authorize("/resources/**", permitAll) (2)
            authorize("/signup", permitAll)
            authorize("/about", permitAll)

            authorize("/admin/**", hasRole("ADMIN")) (3)
            authorize("/db/**", "hasRole('ADMIN') and hasRole('DBA')") (4)
            authorize(anyRequest, denyAll) (5)
        }
    }
}
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 都将被拒绝访问。
如果你不想意外地忘记更新授权规则,这是一个很好的策略。

授权 HTTP 请求基于表达式的访问控制