web-dev-qa-db-fra.com

Ajout d'un en-tête d'autorisation à Jersey SSE Demande du client

J'utilise un client Jersey pour me connecter à un flux SSE. Le serveur nécessite que j'ajoute un en-tête à la demande http pour autorisation, mais je ne vois pas comment ajouter cet en-tête.

Voici mon code:

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

Voici un exemple de l'en-tête que je dois ajouter:

Authorization: Bearer 38bb7b318cc6898c80317decb34525844bc9db55
11
Quick

Ce serait quelque chose comme ceci pour l'authentification de base:

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

...

Vous avez déjà le mot de passe encodé par Jersey.

Et si c'est un jeton:

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

J'espère que ça aide!

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

J'espère que cela vous aide avec votre problème. 

3
Tekle

Dans le cas où quelqu'un voudrait ajouter l'en-tête de jeton de support au niveau de l'entité Client lui-même, plutôt qu'au niveau de l'entité Request (dans mon cas, j'avais une méthode de fabrique pour renvoyer des entités Client préconfigurées, je n'avais donc aucun moyen d'ajouter l'en-tête d'autorisation. dans la méthode d'usine, comme .header(...) devient disponible seulement après avoir suivi la chaîne d'appels ClientBuilder.newBuilder().register(...).build().target(...).request(...), à partir de 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(...)

Malheureusement (comme vous l'avez peut-être deviné), cela nécessite une nouvelle dépendance: org.glassfish.jersey.security:oauth2-client

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

Essaye ça:

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

Je me rends compte que cette question remonte à un an, mais comme il n’ya pas beaucoup à trouver sur ce sujet, je vais partager ma solution.

Sur la base de la suggestion OAuth2Feature, j'ai proposé cette solution:

  1. Créez une fonctionnalité personnalisée. La fonctionnalité référencera un filtre personnalisé
  2. Créez un filtre personnalisé de priorité HEADER_DECORATOR
  3. Créez une interface HeaderProvider. Le fournisseur sera passé au filtre
  4. Enregistrez le Web Client avec la fonctionnalité personnalisée

Interface du fournisseur d'en-tête

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

Fonction personnalisée

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

Filtre personnalisé

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

Utilisation

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 = ....

Cette solution est générique et vous permet d'ajouter facilement un en-tête d'autorisation sans avoir à ajouter une autre dépendance. 

1
Gilles

La réponse suivante est utile: Le client d’événement envoyé par le serveur avec un cookie supplémentaire Il utilise un WebTarget personnalisé pour ajouter un 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);
    }

}

Voici le code pour l'utiliser:

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

Voici les exemples complets

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

Dépendance pour le client du maillot

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

0
Varun

Si vous utilisez un client jersey en utilisant l'en-tête dans webresource

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