如何为WebFlux安全配置2步滤波器链

发布于 2025-02-10 03:13:01 字数 953 浏览 1 评论 0原文

我需要支持两种类型的auth:

  1. 信任系统,其中令牌由自动配置过滤器注入。
  2. 像用户类用户一样,我们从内部应用程序获得令牌并测试我们的服务返回的内容。这仅在我们的Corp网络中起作用(如果细节很重要)。

我的任务是以某种方式验证服务器端的令牌,如果两个方法有效,则应允许访问。

我的初始(幼稚)实现的代码证明了该功能:

RemoteAddressSource remoteAddressSource = new WebFluxRemoteAddressSource(exchange);
        return validateNotBlank(token)
                .switchIfEmpty(Mono.defer(() -> iafTokenValidator.validateToken(remoteAddressSource)
                        .onErrorResume(AuthenticationFailedException.class, e -> tfTokenValidator.validateToken(remoteAddressSource))))
                .onErrorResume(AuthenticationFailedException.class, e -> sendErrorResponse(e, exchange))
                .switchIfEmpty(chain);

在工作和否认并允许预期的情况下,这种方法有几个问题:

  1. 这对两种形式的身份验证,而不是为他们提供2个类。
  2. 如果无效,最终用户总是“查看”后一个错误消息,而它可能源于第一个方法。
  3. 我敢肯定,有一种正确配置的过滤链可以做到这一点,尽管我尚未找到这一点。

I need to support 2 types of auth:

  1. trust system where the tokens are injected by an autoconfigured filter.
  2. postman like usecases where we get tokens from an inner app and test what our services return. This only works in our corp network (if that details is important).

My task is to validate the tokens on the server side in a way that if either of the methods is valid, I should allow the access.

My code for the initial (naive) implementation demonstrating the functionality is:

RemoteAddressSource remoteAddressSource = new WebFluxRemoteAddressSource(exchange);
        return validateNotBlank(token)
                .switchIfEmpty(Mono.defer(() -> iafTokenValidator.validateToken(remoteAddressSource)
                        .onErrorResume(AuthenticationFailedException.class, e -> tfTokenValidator.validateToken(remoteAddressSource))))
                .onErrorResume(AuthenticationFailedException.class, e -> sendErrorResponse(e, exchange))
                .switchIfEmpty(chain);

While working and denies and allows as expected, there are several problems with this approach:

  1. This couples both forms of authentication instead of having 2 classes for them.
  2. In case of not valid, the end user always "sees" the latter error message while it could stem from the first method.
  3. I'm sure there is a proper way to do that with a properly configured filter-chain, though I haven't found any to this point.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温柔嚣张 2025-02-17 03:13:01

我想出了一些有效的东西,尽管我对此不满意。

我想要一个解决方案,在该解决方案中,令牌可以通过这两个选项运行,并且如果验证了请求,但是我希望它们完全分开和彼此遗忘,这是我通过Tokenauthmanager部分实现的。

不过,当无信任表格被弃用时,我们需要更改authmanager,而不仅仅是删除此代码。

另外,我不喜欢IF语句,并尝试/捕获/捕获块以与反应式操作员进行例外处理,因此仍然不理想。

至少它是1堂课,所以我们不是在看很多工作:

 @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
        ServiceAuthentication serviceAuthentication = (ServiceAuthentication) authentication;
        String stripped = serviceAuthentication.getCredentials().toString().replaceAll("Bearer ", "").trim();
        try {
            ServicePrincipal principal = stv.validate(stripped, (String) serviceAuthentication.getDetails());
            log.debug("client {} from ip {} allowed", principal.getName(), authentication.getDetails());
            //if this is valid, return
            authentication.setAuthenticated(true);
            return Mono.just(authentication);
        } catch (TokenException e) {
            log.debug("token {} invalid for TF", authentication.getCredentials());
            if (serviceAuthentication.isPureTf()) {
                return Mono.error(new BadCredentialsException("The provided TF token is invalid", e));
            }
            return iafTokenValidator.authenticate(serviceAuthentication);
        }
    }

I have come up with something that works, though I'm not fully happy about it.

I wanted a solution where the token runs through both options, and if either validates, the request is allowed, but I wanted them to be totally separated and oblivious to each other, which I have partially achieved through TokenAuthManager.

Still, when the none trust form is deprecated, we'll need to change the AuthManager, rather than just deleting this code.

Also, I don't like if statements and try/catch blocks for exception handling with reactive operators, so still not ideal.

As least it's in 1 class, so we're not looking at a lot of work:

 @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
        ServiceAuthentication serviceAuthentication = (ServiceAuthentication) authentication;
        String stripped = serviceAuthentication.getCredentials().toString().replaceAll("Bearer ", "").trim();
        try {
            ServicePrincipal principal = stv.validate(stripped, (String) serviceAuthentication.getDetails());
            log.debug("client {} from ip {} allowed", principal.getName(), authentication.getDetails());
            //if this is valid, return
            authentication.setAuthenticated(true);
            return Mono.just(authentication);
        } catch (TokenException e) {
            log.debug("token {} invalid for TF", authentication.getCredentials());
            if (serviceAuthentication.isPureTf()) {
                return Mono.error(new BadCredentialsException("The provided TF token is invalid", e));
            }
            return iafTokenValidator.authenticate(serviceAuthentication);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文