我正在尝试在http会话中持久化用户,并使用自定义过滤器验证网关内部的身份验证请求。我也发现了一个similar question:
安全配置:
@Configuration
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(
ServerHttpSecurity http,
MyAuthenticationFilter myAuthenticationFilter
) {
http
.csrf()
.disable()
.authorizeExchange()
.pathMatchers("/**")
.permitAll()
.and()
.addFilterAt(myAuthenticationFilter, SecurityWebFiltersOrder.FIRST); // custom filter
return http.build();
}
我的验证筛选器:
@Component
public class MyAuthenticationFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
exchange.getSession().map(
session -> {
session.getAttributes().put("userId", "id123");
// It does not print anything
System.out.println("userId in session: " + session.getAttribute("userId"));
return session;
}
);
return chain.filter(exchange);
}
}
通过添加一个自定义过滤器,并尝试读取/写入会话属性,正如我在调试模式中观察到的那样,map()
内部的函数永远不会执行,终端中也不会输出任何内容。(不出所料,下游服务无法从会话中读取userId
,即使网关和服务共享同一个会话)。
为什么它不工作?这里是一个最小的复制版本:Github repo,请看一下。
1条答案
按热度按时间x3naxklr1#
找到解决方法:
通过将servlet应用程序设置为执行授权的下游服务,“授权服务”内部的阅读/写会话将相对容易一些(因为网关和直接下游服务将共享同一会话)。
对于这个微服务架构中的整个认证/授权部分,我发现使用JWT更可取,并且建议在服务之间应该是无状态的,而网关可以是有状态的,以便与所说的“授权服务”共享会话。
一个great answer,以可视化方式解释JWT实现。