Добавление заголовка авторизации в запрос клиента Джерси SSE
Я использую клиент Джерси для подключения к потоку 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
Ответы
Ответ 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, "...");
...
Вы уже получили пароль, закодированный Джерси.
И если это токен:
Client client = ClientBuilder.newClient();
WebTarget target = client.target(baseurl + "/v1/devices/events/")
.request("...")
.header(HttpHeaders.AUTHORIZATION, "Bearer " + "... encoded token ...");
Надеюсь, что это поможет!
Ответ 2
// 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);
Надеюсь, это поможет вам в решении вашей проблемы.
Ответ 3
Попробуйте следующее:
Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, "Bearer38bb7b318cc6898c80317decb34525844bc9db55");
Ответ 4
В случае, если кто-то захочет добавить заголовок токена-носителя на уровне уровня Client
сам, а не на уровне сущности Request
(в моем случае у меня был метод factory для возврата предварительно сконфигурированных объектов Client
, поэтому у меня не было возможности добавить заголовок авторизации в метод factory, так как .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, я придумал это решение:
- Создайте пользовательскую функцию. Функция будет ссылаться на настраиваемый фильтр.
- Создайте собственный фильтр приоритета HEADER_DECORATOR
- Создайте интерфейс HeaderProvider. Поставщик будет передан в фильтр
- Зарегистрируйте 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 = ....
Это решение является общим и позволяет легко добавлять заголовок авторизации без необходимости добавлять другую зависимость.
Ответ 6
Следующий ответ полезен:
Клиент отправленного сервера с дополнительным 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) {
//...
}
});
Ответ 7
Если вы используете 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);