Java 当使用Oltu传递给OAuthTokenRequest时,无法使用@Context HttpServletRequest检索post数据

Java 当使用Oltu传递给OAuthTokenRequest时,无法使用@Context HttpServletRequest检索post数据,java,oauth-2.0,jax-ws,oltu,Java,Oauth 2.0,Jax Ws,Oltu,我正在为Oauth2使用Oltu 使用@Context HttpServletRequest时,我无法检索post数据 当我使用@FormParam时,我能够检索post数据 将请求传递给OAuthTokenRequest时 OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request); 我得到以下错误 {“错误”:“无效的请求”,“错误描述”:“缺少授权类型参数值”} 在oltu OAuthTokenRequest类上调试时,

我正在为Oauth2使用Oltu

使用@Context HttpServletRequest时,我无法检索post数据

当我使用@FormParam时,我能够检索post数据

将请求传递给OAuthTokenRequest时

OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request);
我得到以下错误

{“错误”:“无效的请求”,“错误描述”:“缺少授权类型参数值”}

在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的post数据 所以,我的问题是

如何在jax ws中使用post数据获取HttpServletRequest请求 这样我就可以将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);
找到解决方法(阅读注释)

Jersey正在使用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;
    }
}
公共类OAuthRequestWrapper扩展了HttpServletRequestWrapper{
私有多值映射形式;
公共OAuthRequestWrapper(HttpServletRequest请求,多值映射表单)
{super(request);this.form=form;}
@凌驾
公共字符串getParameter(字符串名称){
字符串值=super.getParameter(名称);
如果(值==null)
{value=form.getFirst(name);}
返回值;
}
}
下面是如何实现令牌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));

    [...]

}
@POST
@路径(“/token”)
@使用(“应用程序/x-www-form-urlencoded”)
@生成(“应用程序/json”)
公共响应令牌(@Context-HttpServletRequest-request,多值映射形式){
[...]
OAuthTokenRequest oauthRequest=新的OAuthTokenRequest(新的OAuthRequestWrapper(请求,表单));
[...]
}

还有一个问题,资源服务器端点无法从post请求中检索令牌值(作为jax rs实现),这是因为资源服务器代码中的验证程序接口实现使用

httpServletRequest.getParameterValues(param);
这个问题可以通过在Matteo提出的同一个HttpServletRequestWrapper中重写String[]getParameterValues(String)来解决,注意额外的条件,捕获空令牌请求很重要(如果没有传递令牌,则该方法应返回null):


在ApacheOLTU1.0.0中,我发现了另一个解决此限制的选项,即无法在JAX-RS处理程序中获取oltu所需的参数

不使用HttpServletRequestWrapper对象,只需在WebFilter实现中调用HttpServletRequest.getParameterMap()方法。这将使用请求的所有参数加载请求对象的缓存参数映射,使这些参数在该请求对象的生命周期内可用

我更喜欢这种方法,因为它使JAX-RS处理程序更干净,而且我已经在使用WebFilter来拒绝对所有没有有效令牌的非oauth请求的访问


我已经在Jersey和CXF中验证了这一点。

谢天谢地,我终于看到了您的答案。这花了我好几个小时。@Matteo Pacini,在黑暗中寻找解决方案后,我偶然发现了这条线索。。。让它工作起来。。。非常感谢您在此处发布解决方案!:)干得好,谢谢!对我来说,这个答案的关键是了解到,将多值dmap添加到端点方法是很简单的,jax-rs服务(在我的例子中是Jersey)将在那里提供参数。我不需要创建请求包装器,关键是找到可以找到原始表单数据的地方!干得好,谢谢!对我来说,这个答案的关键是了解到,将多值dmap添加到端点方法是很简单的,jax-rs服务(在我的例子中是Jersey)将在那里提供参数。我不需要创建请求包装器,关键是找到可以找到原始表单数据的地方!
@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;
}