对于最新的稳定版本,请使用 Spring Security 6.5.3spring-doc.cadn.net.cn

授权 ServerHttpRequest

Spring Security 支持授权传入的 HTTP 请求。默认情况下,Spring Security 的授权将要求所有请求都经过身份验证。显式配置如下所示:spring-doc.cadn.net.cn

所有请求都需要经过身份验证的用户
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        .authorizeExchange(exchanges -> exchanges
            .anyExchange().authenticated()
        )
        .httpBasic(withDefaults())
        .formLogin(withDefaults());
    return http.build();
}
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        authorizeExchange {
            authorize(anyExchange, authenticated)
        }
        formLogin { }
        httpBasic { }
    }
}

我们可以通过按优先级顺序添加更多规则来将 Spring Security 配置为具有不同的规则。spring-doc.cadn.net.cn

多个授权请求规则
import static org.springframework.security.authorization.AuthorityReactiveAuthorizationManager.hasRole;
// ...
@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.authorizeExchange((authorize) -> authorize                          (1)
			.pathMatchers("/resources/**", "/signup", "/about").permitAll()  (2)
			.pathMatchers("/admin/**").hasRole("ADMIN")                      (3)
			.pathMatchers("/db/**").access((authentication, context) ->      (4)
				hasRole("ADMIN").check(authentication, context)
					.filter(decision -> !decision.isGranted())
					.switchIfEmpty(hasRole("DBA").check(authentication, context))
			)
			.anyExchange().denyAll()                                         (5)
		);
	return http.build();
}
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        authorizeExchange {                                                           (1)
            authorize(pathMatchers("/resources/**", "/signup", "/about"), permitAll)  (2)
            authorize("/admin/**", hasRole("ADMIN"))                                  (3)
            authorize("/db/**", { authentication, context ->                          (4)
                hasRole("ADMIN").check(authentication, context)
                    .filter({ decision -> !decision.isGranted() })
                    .switchIfEmpty(hasRole("DBA").check(authentication, context))
            })
            authorize(anyExchange, denyAll)                                           (5)
        }
        // ...
    }
}
1 指定了多个授权规则。每个规则都按声明的顺序考虑。
2 我们指定了任何用户都可以访问的多个 URL 模式。具体来说,如果 URL 以“/resources/”开头、等于“/signup”或等于“/about”,则任何用户都可以访问请求。
3 任何以“/admin/”开头的 URL 都将仅限于具有“ROLE_ADMIN”权限的用户。您会注意到,由于我们调用了hasRole方法,我们不需要指定“ROLE_”前缀。
4 任何以“/db/”开头的 URL 都要求用户同时拥有“ROLE_ADMIN”和“ROLE_DBA”。这演示了提供自定义ReactiveAuthorizationManager允许我们实现任意授权逻辑。为简单起见,该示例使用 lambda 并将委托给现有的AuthorityReactiveAuthorizationManager.hasRole实现。 但是,在现实世界中,应用程序可能会在适当的类中实现逻辑ReactiveAuthorizationManager.
5 任何尚未匹配的 URL 都将被拒绝访问。如果您不想意外忘记更新授权规则,这是一个很好的策略。