什么可能导致原始'OAuth2'状态参数在org.springframework.social.connect.web.ConnectSupport中为null?

时间:2016-09-13 11:42:18

标签: oauth-2.0 spring-social spring-social-facebook

我正在尝试在我的应用程序上使用Spring Social,并且在调试时注意到我的应用程序上原始的“OAuth2”状态参数始终为null。

请参阅下面org.springframework.social.connect.web.ConnectSupport的Spring社交源代码:

private void verifyStateParameter(NativeWebRequest request) {
    String state = request.getParameter("state");
    String originalState = extractCachedOAuth2State(request);//Always null...
    if (state == null || !state.equals(originalState)) {
        throw new IllegalStateException("The OAuth2 'state' parameter is missing or doesn't match.");
    }
}

private String extractCachedOAuth2State(WebRequest request) {
    String state = (String) sessionStrategy.getAttribute(request, OAUTH2_STATE_ATTRIBUTE);
    sessionStrategy.removeAttribute(request, OAUTH2_STATE_ATTRIBUTE);
    return state;       
}

有人可以帮忙吗?

编辑:我确实看到facebook传递的状态参数:

Request URL:https://www.facebook.com/v2.5/dialog/oauth?client_id=414113641982912&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fconnect%2Ffacebook&scope=public_profile&state=0b7a97b5-b8d1-4f97-9b60-e3242c9c7eb9
Request Method:GET
Status Code:302 
Remote Address:179.60.192.36:443

编辑2 :顺便说一句,我得到的例外情况如下:

Exception while handling OAuth2 callback (The OAuth2 'state' parameter is missing or doesn't match.). Redirecting to facebook connection status page.

3 个答案:

答案 0 :(得分:3)

事实证明,问题是由于我依赖于标题 - 而不是Cookie - 来管理会话。

通过注释掉以下spring会话配置bean:

@Bean
public HttpSessionStrategy sessionStrategy(){
    return new HeaderHttpSessionStrategy();
}

对oauth2状态参数问题进行了排序。

P.S。 现在我必须找到一种方法让Spring Social使用我当前的Spring Session配置...

编辑:我设法保留了HeaderHttpSessionStrategy(在春季会话方面)并通过实现我自己的SessionStrategy(在春季社交方面)使其工作,如下所示:

public class CustomSessionStrategy implements SessionStrategy {

    public void setAttribute(RequestAttributes request, String name, Object value) {
        request.setAttribute(name, value, RequestAttributes.SCOPE_SESSION);
    }

    public Object getAttribute(RequestAttributes request, String name) {
        ServletWebRequest servletWebRequest = (ServletWebRequest) request;
        return servletWebRequest.getParameter(name);
    }

    public void removeAttribute(RequestAttributes request, String name) {
        request.removeAttribute(name, RequestAttributes.SCOPE_SESSION);
    }
}

答案 1 :(得分:0)

尝试这项工作,看看它是否适合您:

令我惊讶的是,我在“隐身”浏览器中打开了应用程序,一切正常。就像那样。我认为在缓存某些内容之前会导致问题。

今天我遇到了这个问题,我的应用程序运行得非常好。我刚休息几个小时,当我再次运行时,它开始抱怨'OAuth2'状态'参数缺失或不匹配。 状态参数首先被放入会话然后请求发送到facebook并且请求返回相同的状态参数但是当spring正在查找会话对象以获取状态参数时,它没有找到会话。我认为它没有找到会话,因为当请求返回时它认为它是一个不同的客户端(或主机),即使旧的HttpSession对象仍然存在。容器为每个客户端维护一个HttpSession。

答案 2 :(得分:-1)

您从Facebook获得的不是请求属性,它是一个请求参数。

你应该通过以下方式获得它:

ajaxRequest.success(function (html) {
    utility.storePageIn(cache, settings.url, html, elementId);
    $container.data('smoothState').cache = cache;
});