当前位置: 首页 > 知识库问答 >
问题:

使用Apache Camel AHC-WS Websocket组件进行JWT承载令牌身份验证

袁秦迟
2023-03-14

我们目前正在使用Apache Camel作为集成框架设置一个Springboot项目。

在路由的最后,我们需要使用WSS websocket协议发送消息,其中我们的应用程序充当客户机,需要将消息发送到公开websocketendpoint的远程服务器。

但是远程服务器首先需要在WSS握手期间进行身份验证。事实上,它需要一些特定的HTTP头,包括Authorization:Bearer{jwt-bearer-token}头。只有在握手过程中才需要该令牌。打开websocket后,不再需要进一步的身份验证。

...

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-spring-boot-starter</artifactId>
    <version>3.0.0-M2</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-ahc-ws</artifactId>
    <version>3.0.0-M2</version>
</dependency>

...
<?xml version="1.0" encoding="UTF-8"?>
<routes xmlns="http://camel.apache.org/schema/spring">
    <route id="distributorRoute">
        <from uri="seda:distributorEntryPoint"/>
        <setHeader headerName="Authorization">
            <simple>Bearer {jwt-bearer-token}</simple>
        </setHeader>
        <log message="${header.Authorization}"/>
        <to uri="ahc-wss://{remote-server-wss-endpoint}>
    </route>
</routes>
2019-06-07 15:52:00.304  INFO 17164 --- [butorEntryPoint] o.a.camel.component.ahc.ws.WsEndpoint    : Reconnecting websocket: wss://{remote-server-wss-endpoint}

...

java.lang.NullPointerException: null
    at org.apache.camel.component.ahc.ws.WsProducer.sendMessage(WsProducer.java:76) ~[camel-ahc-ws-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.component.ahc.ws.WsProducer.process(WsProducer.java:51) ~[camel-ahc-ws-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.support.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:66) ~[camel-support-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:130) ~[camel-core-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.processor.RedeliveryErrorHandler$RedeliveryState.run(RedeliveryErrorHandler.java:482) ~[camel-core-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.support.ReactiveHelper$Worker.schedule(ReactiveHelper.java:130) [camel-support-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.support.ReactiveHelper.scheduleMain(ReactiveHelper.java:43) [camel-support-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:88) [camel-core-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:221) [camel-core-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.component.seda.SedaConsumer.sendToConsumers(SedaConsumer.java:289) [camel-seda-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.component.seda.SedaConsumer.doRun(SedaConsumer.java:203) [camel-seda-3.0.0-M2.jar:3.0.0-M2]
    at org.apache.camel.component.seda.SedaConsumer.run(SedaConsumer.java:148) [camel-seda-3.0.0-M2.jar:3.0.0-M2]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135) [na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [na:na]
    at java.base/java.lang.Thread.run(Thread.java:844) [na:na]

我们已经查找了AHC-WS组件的配置可能性,但似乎没有一个适合这种情况。

此外,我们需要动态生成和添加令牌,所以硬编码不会有帮助。

共有1个答案

齐承运
2023-03-14

@paizo的注释使我们想到在自定义DefaultAsynchTtpClient实现中覆盖Prepareget()方法:

@Override
public BoundRequestBuilder prepareGet(String url) {
    // OAuth token
    String token = "Bearer my-jwt-token";

    // Headers for the handshake request
    HttpHeaders httpHeaders = new DefaultHttpHeaders();
    httpHeaders.set("Authorization", token);

    // Prepare the websocket upgrade handshake
    BoundRequestBuilder boundRequestBuilder = super.prepareGet(url);
    boundRequestBuilder.setHeaders(httpHeaders);    

    return boundRequestBuilder;
}

这个客户端现在必须由AHC-WS组件使用。实际上,wsendpoint类在connect()方法期间使用了它,其中getclient()必须从上面返回自定义客户机:

public void connect() throws Exception {
    String uri = getHttpUri().toASCIIString();

    log.debug("Connecting to {}", uri);
    websocket = getClient().prepareGet(uri).execute(
        new WebSocketUpgradeHandler.Builder()
            .addWebSocketListener(listener).build()).get();
}

不幸的是,AHC-WS组件不能作为Spring bean使用,但是可以在application.yml中指向自定义客户机:

camel:
  component:
    ahc-ws:
      client: myCustomAsyncHttpClientImpl
 类似资料:
  • 我正在尝试为我的应用程序构建一个身份验证解决方案。我使用React作为前端,使用API模式下的Rails作为后端。我有一个外部身份验证解决方案,我需要使用它。我无意中发现了Knock for JWT令牌管理,但我不理解文档,尤其是这部分“它必须有一个身份验证方法,类似于has_secure_password添加的方法”,因为由于我的外部身份验证服务,我没有用户模型。因此,在我的头脑中,登录请求将发

  • 我正在开发一个使用Spring Boot 2.4.1和Spring Security 5.4.2的Web应用程序,我需要提供HTTP基本身份验证和持有者令牌身份验证(JWT访问令牌从SPA发送用于每次API调用)。所有 API URL 都以路径 /api 开头,并且必须使用持有者令牌进行身份验证,但使用 HTTP Basic 所需的两个 URL(/api/func1 和 /api/func2)除外

  • 是否可以在ASP中支持多个JWT令牌发行者。净核心2?我想为外部服务提供一个API,我需要使用两个JWT代币来源——Firebase和定制JWT代币发行人。在ASP。NET core I可以为承载身份验证方案设置JWT身份验证,但只能为一个机构设置: 我可以有多个发行人和受众,但我不能设置多个权限。

  • jwt不应该仅仅用于认证用户吗?我读到过可以在里面存储非敏感的东西,比如用户ID。将权限级别之类的东西存储在令牌中可以吗?这样我可以避免数据库调用。

  • 我正在尝试在ASP.NET5中实现OAuth承载令牌身份验证,并且正在努力寻找一个如何实现这一点的示例,因为OWIN的东西在ASP.NET5中发生了变化。 例如IApplicationBuilder.UseOAuthAuthorizationServer()和IApplicationBuilder。UseOAuthBearerAuthentication()要么不再存在,要么缺少引用? 如有任何指

  • 致命:“https://github.com/scuzzlebuzzle/ol3-1.git/'”身份验证失败