Не удалось извлечь данные post, используя @Context HttpServletRequest при передаче в OAuthTokenRequest с помощью Oltu
Я использую Oltu для Oauth2.
При использовании запроса @Context HttpServletRequest я не могу извлечь данные сообщения
Когда я использую @FormParam, я могу извлекать данные post.
При передаче запроса на OAuthTokenRequest
OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request);
Я получаю следующую ошибку
{ "error": "invalid_request", "error_description": "Отсутствует значение параметра grant_type" }
При отладке в классе oltu OAuthTokenRequest следующий код используется для извлечения значения параметра
public String getParam(String name) {
return this.request.getParameter(name); // from request it is unable to get post data.As i am getting request object using @Context HttpServletRequest request .
}
Говорят, что с помощью запроса @Context HttpServletRequest невозможно получить почтовые данные для использования запроса @Context HttpServletRequest
Итак, мой вопрос:
Как получить запрос HttpServletRequest с данными post в jax-ws так что я могу передать запрос HttpServletRequest в OAuthTokenRequest
Это мой код
@Path("/token")
public class TokenEndpoint {
@POST
@Consumes("application/x-www-form-urlencoded")
@Produces("application/json")
public Response authorize(@FormParam("state") String state,@Context HttpServletRequest request) throws OAuthSystemException {
try {
// here i am unable to get value of request.getParameter("state")
// but using (@FormParam("state") i am able to get value of post parameter state
request.getParameter("state");
// exception is thrown from following code
OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request);
Ответы
Ответ 1
Обнаружено обходное решение (читайте комментарии).
Ошибка OLTU №26
Джерси потребляет данные POST.
Решение состоит в том, чтобы обернуть HttpServletRequest и переопределить getParameters()
.
Это оболочка:
public class OAuthRequestWrapper extends HttpServletRequestWrapper {
private MultivaluedMap<String, String> form;
public OAuthRequestWrapper(HttpServletRequest request, MultivaluedMap<String, String> form)
{ super(request); this.form = form; }
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null)
{ value = form.getFirst(name); }
return value;
}
}
И вот как реализовать метод POST-токена:
@POST
@Path("/token")
@Consumes("application/x-www-form-urlencoded")
@Produces("application/json")
public Response token(@Context HttpServletRequest request, MultivaluedMap<String, String> form) {
[...]
OAuthTokenRequest oauthRequest = new OAuthTokenRequest(new OAuthRequestWrapper(request, form));
[...]
}
Ответ 2
Также возникает проблема с конечной точкой сервера ресурсов, которая не может получить значения токена из пост-запросов (трикотаж как реализация jax-rs), это связано с тем, что реализации интерфейса валидатора в коде сервера ресурсов используют
httpServletRequest.getParameterValues(param);
эта проблема может быть решена путем переопределения String [] getParameterValues (String) в том же HttpServletRequestWrapper, предложенном Matteo, обратите внимание на дополнительное условие, это важно для поиска пустых запросов токена (метод должен возвращать null, если не передан токен)
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if(values == null && form.get(name) != null){
values = new String[form.get(name).size()];
values = form.get(name).toArray(values);
}
return values;
}
относящийся к apache oltu 1.0.0
Ответ 3
Я нашел еще один вариант этого ограничения того, что не смог получить параметры, необходимые для oltu в обработчике JAX-RS.
Вместо использования объекта HttpServletRequestWrapper просто вызовите метод HttpServletRequest.getParameterMap() внутри вашей реализации WebFilter. Это будет загружать карту кэша параметров объекта запроса со всеми параметрами запроса, делая эти параметры доступными для жизни этого объекта запроса.
Я предпочитаю этот метод, поскольку он делает обработчик JAX-RS более чистым, и я уже использую WebFilter, чтобы запретить доступ ко всем не-oauth-запросам без действительного токена.
Я подтвердил, что это работает как в Джерси, так и в CXF.