Resteasy POST вызов OAuth2 для получения токена - PullRequest
0 голосов
/ 22 февраля 2020

Мне нужно запросить токен OAuth2, который был размещен в другой команде. У меня возникают трудности при построении запроса с помощью RestEasy (3.0.19).

Поэтому в Postman я пытаюсь смоделировать вызов и это успех, как и ожидалось.

Basic Authentication Header Body Result

Ниже приведен код:

Создание прокси с Basi c Аутентификация, которая реализует ClientRequestFilter

@Produces
public TokenService produceTokenService() {
    log.debug("produceTokenService");

    return createProxyWithBasicAuth(authenticationUrlFromProperties, TokenService.class);
}

private <T> T createProxyWithBasicAuth(final String url, final Class<T> clazz, BasicAuthentication basicAuthentication) {
    final ResteasyWebTarget target = createBasicProxy(url);    

    target.register(new Authenticator("my_username", "my_password"));

    return target.proxy(clazz);
}

private ResteasyWebTarget createBasicProxy(final String url) {
    final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
    final CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();
    cm.setMaxTotal(200); // Increase max total connection to 200
    cm.setDefaultMaxPerRoute(20); // Increase default max connection per route (2) to 20
    final ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);

    final ResteasyWebTarget target = new ResteasyClientBuilder().httpEngine(engine).build()
            .target(UriBuilder.fromPath(url));
    return target;
}


public class Authenticator implements ClientRequestFilter{

private final String user;
private final String password;

public Authenticator(String user, String password) {
    this.user = user;
    this.password = password;
}


@Override
public void filter(ClientRequestContext requestContext) throws IOException {
    MultivaluedMap<String, Object> headers = requestContext.getHeaders();
    final String basicAuthentication = getBasicAuthentication();
    headers.add("Authorization", basicAuthentication);

}

private String getBasicAuthentication() {
    String token = this.user + ":" + this.password;
    try {
        return "Basic " +
             DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException ex) {
        throw new IllegalStateException("Cannot encode with UTF-8", ex);
    }
}

}

Тогда это прокси-слой:

@Path("/")
public interface TokenService {
@POST
@Path("/authenticate/oauth/token")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public String tokenRequest(Entity<Form> entityRequest);

Вот как я вызываю прокси:

@Inject
private TokenService tokenService;

public Response authenticateCAA(CAATokenRequest request) {
Response response = null;
    try {

        Form form = new Form();
        form.param("username", "my_username").param("password", "my_password").param("grant_type", "password");
        Entity<Form> entity = Entity.form(form);

        String responseString = tokenService.tokenRequest(entity);

    } catch (Exception e) {
        e.printStackTrace();
        response = Response.serverError().entity(e.getMessage()).build();
    }
    return response;
}

До этого момента я получаю ошибку ниже:

Не найден сериализатор для класса javax.ws .rs.core.Form и не обнаружено свойств для создания BeanSerializer (во избежание исключения отключите SerializationFeature.FAIL_ON_EMPTY_BEANS)) (через цепочку ссылок: javax.ws.rs.client.Entity ["entity"])

Я использую Entity, потому что согласно запросу OAuth2 мне нужно передать «application / x- www-form-urlencoded»

Мой ожидаемый результат будет таким же ответом, что и через Почтальон. Было бы легко, если бы я использовал Spring RestTemplate, но в этом проекте я не смог импортировать дополнительную библиотеку, такую ​​как RestTemplate.

...