reactive-authorization-authorize-http-requests.md 4.2 KB
Newer Older
dallascao's avatar
dallascao 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
# 授权 ServerHttpRequest

Spring 安全性为授权传入的 HTTP 请求提供了支持。默认情况下, Spring Security 的授权将要求对所有请求进行身份验证。显式配置如下所示:

例 1。所有请求都需要经过身份验证的用户。

爪哇

```
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        .authorizeExchange(exchanges -> exchanges
            .anyExchange().authenticated()
        )
        .httpBasic(withDefaults())
        .formLogin(withDefaults());
    return http.build();
}
```

Kotlin

```
@Bean
fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        authorizeExchange {
            authorize(anyExchange, authenticated)
        }
        formLogin { }
        httpBasic { }
    }
}
```

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

例 2。多个授权请求规则

爪哇

```
import static org.springframework.security.authorization.AuthorityReactiveAuthorizationManager.hasRole;
// ...
@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
	// @formatter:off
	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)
		);
	// @formatter:on
	return http.build();
}
```

Kotlin

```
@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**|指定了多个授权规则。<br/>每个规则都按照它们被声明的顺序被考虑。|
|-----|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|**2**|我们指定了任何用户都可以访问的多个 URL 模式。<br/>具体来说,如果 URL 以“/resources/”开头,等于“/signup”或等于“/about”,则任何用户都可以访问请求。|
|**3**|任何以“/admin/”开头的 URL 都将被限制为具有“role\_admin”权限的用户。<br/>你将注意到,由于我们正在调用`hasRole`方法,因此我们不需要指定“role\_”前缀。|
|**4**|任何以“/db/”开头的 URL 都需要用户同时具有“role\_admin”和“role\_DBA”。<br/>这表明了提供自定义`ReactiveAuthorizationManager`的灵活性,允许我们实现任意的授权逻辑。<br/>为了简单起见,示例使用 lambda 并将其委托给现有的`AuthorityReactiveAuthorizationManager.hasRole`实现。<br/>但是,在实际情况下,应用程序可能会在实现`ReactiveAuthorizationManager`的适当类中实现该逻辑。|
|**5**|任何尚未匹配的 URL 都将被拒绝访问。<br/>如果你不想意外地忘记更新授权规则,这是一个很好的策略。|