将授权标头添加到Jersey SSE Client请求

时间:2015-03-15 00:53:06

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

我正在使用Jersey客户端连接到SSE流。服务器要求我在http请求中添加标题以进行授权,但我无法弄清楚如何添加标题。

这是我的代码:

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

8 个答案:

答案 0 :(得分:21)

基本身份验证会是这样的:

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 ...");

希望它有所帮助!

答案 1 :(得分:4)

// 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);

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

答案 2 :(得分:2)

如果有人想要在Client实体级别本身添加承载令牌头,而不是在Request实体级别添加(在我的情况下,我有一个工厂方法来返回预配置的{{ 1}}实体,所以我无法在工厂方法中添加授权标头,因为Client仅在您通过.header(...)调用链后才可用,如Jersey 2.x所示:

ClientBuilder.newBuilder().register(...).build().target(...).request(...)

不幸的是(正如您可能已经猜到的)这需要一个新的依赖:// 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

答案 3 :(得分:1)

试试这个:

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

答案 4 :(得分:1)

我意识到这个问题已经有一年了,但由于在这个问题上找不到很多,我会分享我的解决方案。

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

  1. 创建自定义功能。功能将引用自定义过滤器
  2. 创建优先级为HEADER_DECORATOR的自定义过滤器
  3. 创建HeaderProvider界面。提供者将被传递给过滤器
  4. 使用自定义功能注册WebClient
  5. 标头提供商界面

    @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标头,而无需添加其他依赖项。

答案 5 :(得分:1)

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

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) {
               //...
       }
});

答案 6 :(得分:1)

这是完整的示例

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);

球衣客户的依赖关系

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

答案 7 :(得分:0)

如果您在websource中使用jercy客户端

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