【问题标题】:Adding authorization header to Jersey SSE Client request向 Jersey SSE 客户端请求添加授权标头
【发布时间】:2015-05-17 08:11:08
【问题描述】:

我正在使用 Jersey 客户端连接到 SSE 流。服务器要求我在http请求中添加header进行授权,但是我不知道如何添加header。

这是我的代码:

Client client = ClientBuilder.newBuilder().register(SseFeature.class).build();
WebTarget target = client.target(baseurl + "/v1/devices/events/");
eventSource = EventSource.target(target).build();
eventSource.register(getEventListener());
eventSource.open();

这是我需要添加的标题示例:

Authorization: Bearer 38bb7b318cc6898c80317decb34525844bc9db55

【问题讨论】:

    标签: java http-headers jersey authorization server-sent-events


    【解决方案1】:

    基本身份验证是这样的:

    Client client = ClientBuilder.newClient();
    HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder().build();
    client.register(feature);
    client.register(SseFeature.class);
    WebTarget target = client.target(baseurl + "/v1/devices/events/")
        .property(HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_USERNAME, "...")
        .property(HttpAuthenticationFeature.HTTP_AUTHENTICATION_BASIC_PASSWORD, "...");
    

    ...

    你已经得到了 Jersey 编码的密码。

    如果是令牌:

    Client client = ClientBuilder.newClient();
    WebTarget target = client.target(baseurl + "/v1/devices/events/")
        .request("...")     
        .header(HttpHeaders.AUTHORIZATION, "Bearer " + "... encoded token ...");
    

    希望对你有帮助!

    【讨论】:

    • 我实际上需要使用标题,因为我有一个密钥,而不是用户名和密码。该问题已被编辑以使其更加清晰。对不起。
    • 我已经编辑过了...留下用户/密码部分以防它帮助其他人。对于令牌,您不需要身份验证功能。希望对您有所帮助!
    • 我的 WebTarget 对象 (javax.ws.rs.client.WebTarget) 没有 header() 方法。我试过了,但没有效果:target.request().header("Authorization", "Bearer " + token);
    • 对不起,你是对的,确实是在请求之后。我已经编辑了我的答案。您使用的是哪个版本的Jersey?你能发布你的依赖关系吗? (pom.xml 或同等学历)您所说的“无效”是什么意思?有没有调试过HTTP头有没有?
    • POM 没有效果,我的意思是标题不存在。 Test
    【解决方案2】:

    试试这个:

    Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, "Bearer38bb7b318cc6898c80317decb34525844bc9db55");
    

    【讨论】:

      【解决方案3】:
      // Using SSL + Header Key 
      uri = UriBuilder.fromUri(sslUrl).port(sslServerPort).build();
      sslConfig = SslConfigurator.newInstance().trustStoreFile(trustStoreFile).trustStorePassword(trustStorePassword);
      sslContext = sslConfig.createSSLContext();
      client = ClientBuilder.newBuilder().sslContext(sslContext).build();
      target = client.target(uri).path(path);
      Entity<?> entity = Entity.entity(Object, MediaType.APPLICATION_JSON);
      response = target.request().header("key","value").post(entity);
      
      
      // Using UserName & Password + Header Key 
      uri = UriBuilder.fromUri(url).port(serverPort).build();
      basicAuth = HttpAuthenticationFeature.basic(username, userPassword);
      client = ClientBuilder.newBuilder().register(basicAuth).build();
      target = client.target(uri).path(path);
      Entity<?> entity = Entity.entity(Object, MediaType.APPLICATION_JSON);
      response = target.request().header("key","value").post(entity);
      
      // Using only Header Key 
      uri = UriBuilder.fromUri(url).port(serverPort).build();
      client = ClientBuilder.newBuilder().build();
      target = client.target(uri).path(path);
      Entity<?> entity = Entity.entity(Object, MediaType.APPLICATION_JSON);
      response = target.request().header("key","value").post(entity);
      

      希望这可以帮助您解决问题。

      【讨论】:

        【解决方案4】:

        如果有人想在 Client 实体级别本身而不是在 Request 实体级别添加不记名令牌标头(在我的情况下,我有一个工厂方法用于返回预配置的 Client 实体,所以我无法在工厂方法中添加授权标头,因为 .header(...) 只有在您通过 ClientBuilder.newBuilder().register(...).build().target(...).request(...) 调用链后才可用,从 Jersey 2.x 开始):

        // client is a javax.ws.rs.client.Client entity
        Feature feature = OAuth2ClientSupport.feature("YOUR_BEARER_TOKEN");
        client.register(feature);
        // now you can use client.target(...).request(...).post(...), without calling .header(...) after .request(...)
        

        不幸的是(您可能已经猜到了)这需要一个新的依赖项:org.glassfish.jersey.security:oauth2-client

        <dependency>
          <groupId>org.glassfish.jersey.security</groupId>
          <artifactId>oauth2-client</artifactId>
          <version>2.15</version>
        </dependency>
        

        【讨论】:

          【解决方案5】:

          我知道这个问题已经有一年的历史了,但由于关于该主题的内容不多,所以我将分享我的解决方案。

          根据建议的 OAuth2Feature,我想出了这个解决方案:

          1. 创建自定义功能。功能将引用自定义过滤器
          2. 创建优先级 HEADER_DECORATOR 的自定义过滤器
          3. 创建一个 HeaderProvider 接口。提供者将被传递给过滤器
          4. 使用自定义功能注册 WebClient

          标头提供程序接口

          @FunctionalInterface
          public interface ISseHeaderProvider {
              Map<String, String> getHeaders();  
          } 
          

          自定义功能

          public class SseHeaderSupportFeature implements Feature {
              private final SseHeaderSupportFilter filter;
          
          
              public SseHeaderSupportFeature(ISseHeaderProvider provider) {
                  this.filter = new SseHeaderSupportFilter(provider);
              }
          
              @Override
              public boolean configure(FeatureContext context) {
                  context.register(filter);
                  return true;
              }
          }
          

          自定义过滤器

          @Priority(Priorities.HEADER_DECORATOR)
          public class SseHeaderSupportFilter  implements ClientRequestFilter {
          
              private final ISseHeaderProvider provider;
          
              public SseHeaderSupportFilter(@NotNull ISseHeaderProvider provider) {
                  this.provider = provider;
              }
          
          
              @Override
              public void filter(ClientRequestContext request) throws IOException {
                  provider.getHeaders().forEach((k, v) -> request.getHeaders().add(k, v));
              }
          }
          

          用法

          ISseHeaderProvider provider = () -> MapBuilder.<String, String>builder().add("Authorization", "Bearer ...").build(); 
          Client client = ClientBuilder.newBuilder()
                                       .register(SseFeature.class)
                                       .register(new SseHeaderSupportFeature(provider))
                                       .build();
          WebTarget target = client.target(UriBuilder.fromPath(getUrl()));
          //EventSource eventSource = ....
          

          此解决方案是通用的,允许您轻松添加 Authorization 标头,而无需添加其他依赖项。

          【讨论】:

          • 看起来很有趣。用于实现 ISseHeaderProvider 的 MapBuilder 是什么样的?
          【解决方案6】:

          以下答案很有用: Server Sent Event Client with additional Cookie 它使用自定义的 WebTarget 来添加 cookie,并且在 header 上也可以使用相同的方式。

          public class AuthorizationHeaderWebTarget implements WebTarget {
          
              private WebTarget base;
          
              private String token;
          
              public AuthorizationHeaderWebTarget(WebTarget base, String token) {
                  this.base = base;
                  this.token = token;
              }
          
              // Inject that cookie whenever someone requests a Builder (like EventSource does):
              public Invocation.Builder request() {
                  return base.request().header(HttpHeaders.AUTHORIZATION, token);
              }
          
              public Invocation.Builder request(String... paramArrayOfString) {
                  return base.request(paramArrayOfString).header(HttpHeaders.AUTHORIZATION, token);
              }
          
              public Invocation.Builder request(MediaType... paramArrayOfMediaType) {
                  return base.request(paramArrayOfMediaType).header(HttpHeaders.AUTHORIZATION, token);
              }
          
              public Configuration getConfiguration() {
                  return base.getConfiguration();
              }
          
              //All other methods from WebTarget are delegated as-is:
          
              public URI getUri() {
                  return base.getUri();
              }
          
              public UriBuilder getUriBuilder() {
                  return base.getUriBuilder();
              }
          
              public WebTarget path(String paramString) {
                  return base.path(paramString);
              }
          
              public WebTarget matrixParam(String paramString, Object... paramArrayOfObject) {
                  return base.matrixParam(paramString, paramArrayOfObject);
              }
          
              public WebTarget property(String paramString, Object paramObject) {
                  return base.property(paramString, paramObject);
              }
          
              public WebTarget queryParam(String paramString, Object... paramArrayOfObject) {
                  return base.queryParam(paramString, paramArrayOfObject);
              }
          
              public WebTarget register(Class<?> paramClass, Class<?>... paramArrayOfClass) {
                  return base.register(paramClass, paramArrayOfClass);
              }
          
              public WebTarget register(Class<?> paramClass, int paramInt) {
                  return base.register(paramClass, paramInt);
              }
          
              public WebTarget register(Class<?> paramClass, Map<Class<?>, Integer> paramMap) {
                  return base.register(paramClass, paramMap);
              }
          
              public WebTarget register(Class<?> paramClass) {
                  return base.register(paramClass);
              }
          
              public WebTarget register(Object paramObject, Class<?>... paramArrayOfClass) {
                  return base.register(paramObject, paramArrayOfClass);
              }
          
              public WebTarget register(Object paramObject, int paramInt) {
                  return base.register(paramObject, paramInt);
              }
          
              public WebTarget register(Object paramObject, Map<Class<?>, Integer> paramMap) {
                  return base.register(paramObject, paramMap);
              }
          
              public WebTarget register(Object paramObject) {
                  return base.register(paramObject);
              }
          
              public WebTarget resolveTemplate(String paramString, Object paramObject) {
                  return base.resolveTemplate(paramString, paramObject);
              }
          
              public WebTarget resolveTemplate(String paramString, Object paramObject, boolean paramBoolean) {
                  return base.resolveTemplate(paramString, paramObject, paramBoolean);
              }
          
              public WebTarget resolveTemplateFromEncoded(String paramString, Object paramObject) {
                  return base.resolveTemplateFromEncoded(paramString, paramObject);
              }
          
              public WebTarget resolveTemplates(Map<String, Object> paramMap) {
                  return base.resolveTemplates(paramMap);
              }
          
              public WebTarget resolveTemplates(Map<String, Object> paramMap, boolean paramBoolean) {
                  return base.resolveTemplates(paramMap, paramBoolean);
              }
          
              public WebTarget resolveTemplatesFromEncoded(Map<String, Object> paramMap) {
                  return base.resolveTemplatesFromEncoded(paramMap);
              }
          
          }
          

          以下是使用它的代码:

          EventSource eventSource = new EventSource(new AuthorizationHeaderWebTarget(target, token));
          eventSource.register(new EventListener() {
                 public void onEvent(final InboundEvent inboundEvent) {
                         //...
                 }
          });
          

          【讨论】:

            【解决方案7】:

            如果你在 websource 中使用带有 header 的 jercy 客户端

            Client client=Client.create();          
            WebResource webresource=client.resource(urlLink);
            ClientResponse clientResponse=webresource.header("authorization", accessToken)
                .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
            

            【讨论】:

              【解决方案8】:

              这里是完整的例子

              ClientConfig clientConfig = new ClientConfig();
              Client client = ClientBuilder.newClient(clientConfig);
              WebTarget webTarget = client.target("http://localhost:8080/MyApp/customer/");
              Invocation.Builder invocationBuilder = 
              webTarget.request(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, "your 
              secret key");
              response = invocationBuilder.get();
              output = response.readEntity(String.class);

              jersey 客户端的依赖关系

              <dependency>
                <groupId>org.glassfish.jersey.core</groupId>
                <artifactId>jersey-client</artifactId>
                <version>2.25.1</version>
              </dependency>

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2020-01-24
                • 1970-01-01
                • 1970-01-01
                • 2014-12-28
                • 2020-03-29
                • 1970-01-01
                • 1970-01-01
                • 2020-10-11
                相关资源
                最近更新 更多