PUT 上的 OAuth 身份验证失败

发布于 2024-11-27 11:50:47 字数 2611 浏览 2 评论 0原文

我在我的项目中使用OAuth。但我遇到了身份验证问题。

就是我用“POST”方法可以通过Oauth的认证机制,但用“PUT”方法不行。 POST 和 PUT 请求之间的唯一区别是方法类型。正文和标题相同。我使用的请求如下:

POST

resp, cont = client.request("http://localhost:8000/api/1.0/booking/",
                            "POST", 
                            data_booking,
                            headers=headers) 

PUT

resp, cont = client.request("http://localhost:8000/api/1.0/booking/",
                            "PUT",
                            data_booking,
                            headers=headers)

客户端是 OAuth 客户端。

服务器返回的错误消息是:

在此处输入图像描述

Fyi : 401 Unauthorized

与 403 Forbidden 类似,但专门用于以下情况身份验证是可能的,但已失败或尚未提供

我正在使用 django 框架进行开发。

请求方法如下:

def request(self, uri, method="GET", body=None, headers=None, 
        redirections=httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None,
        callback_url=None, realm=''):
        DEFAULT_CONTENT_TYPE = 'application/x-www-form-urlencoded'

        if not isinstance(headers, dict):
            headers = {}

        is_multipart = method == 'POST' and headers.get('Content-Type', 
            DEFAULT_CONTENT_TYPE) != DEFAULT_CONTENT_TYPE

        if body and (method == "POST" or method == 'PUT') and not is_multipart:
            parameters = dict(parse_qsl(body))
            if callback_url != None:
                parameters['oauth_callback'] = callback_url
        else:
            if callback_url != None and not is_multipart:
                parameters = {'oauth_callback': callback_url}
            else:
                parameters = None

        req = Request.from_consumer_and_token(self.consumer, 
            token=self.token, http_method=method, http_url=uri, 
            parameters=parameters)

        req.sign_request(self.method, self.consumer, self.token)

        if method == "POST" or method == "PUT":
            headers['Content-Type'] = headers.get('Content-Type', 
                DEFAULT_CONTENT_TYPE)
            if is_multipart:
                headers.update(req.to_header(realm))
            else:
                body = req.to_postdata()
        elif method == "GET":
            uri = req.to_url()
        else:
            headers.update(req.to_header(realm))

        return httplib2.Http.request(self, uri, method=method, body=body, 
            headers=headers, redirections=redirections, 
            connection_type=connection_type)

有人有想法吗?

I am using OAuth within my project. but I have come into an authentication problem.

It is that I can pass the authentification mechanism of Oauth with the method "POST" but not the method "PUT". The only difference between the POST and PUT request is the method type. The body and the header is the same. The requests I used are as follows :

POST

resp, cont = client.request("http://localhost:8000/api/1.0/booking/",
                            "POST", 
                            data_booking,
                            headers=headers) 

PUT

resp, cont = client.request("http://localhost:8000/api/1.0/booking/",
                            "PUT",
                            data_booking,
                            headers=headers)

The client is a OAuth client.

The error message returned by server is :

enter image description here

Fyi : 401 Unauthorized

Similar to 403 Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided

I am developing using the django framework.

The request method is as follow :

def request(self, uri, method="GET", body=None, headers=None, 
        redirections=httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None,
        callback_url=None, realm=''):
        DEFAULT_CONTENT_TYPE = 'application/x-www-form-urlencoded'

        if not isinstance(headers, dict):
            headers = {}

        is_multipart = method == 'POST' and headers.get('Content-Type', 
            DEFAULT_CONTENT_TYPE) != DEFAULT_CONTENT_TYPE

        if body and (method == "POST" or method == 'PUT') and not is_multipart:
            parameters = dict(parse_qsl(body))
            if callback_url != None:
                parameters['oauth_callback'] = callback_url
        else:
            if callback_url != None and not is_multipart:
                parameters = {'oauth_callback': callback_url}
            else:
                parameters = None

        req = Request.from_consumer_and_token(self.consumer, 
            token=self.token, http_method=method, http_url=uri, 
            parameters=parameters)

        req.sign_request(self.method, self.consumer, self.token)

        if method == "POST" or method == "PUT":
            headers['Content-Type'] = headers.get('Content-Type', 
                DEFAULT_CONTENT_TYPE)
            if is_multipart:
                headers.update(req.to_header(realm))
            else:
                body = req.to_postdata()
        elif method == "GET":
            uri = req.to_url()
        else:
            headers.update(req.to_header(realm))

        return httplib2.Http.request(self, uri, method=method, body=body, 
            headers=headers, redirections=redirections, 
            connection_type=connection_type)

Anyone has an idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

始于初秋 2024-12-04 11:50:47

当 HTTP 方法为 POST 时,某些 OAuth 服务器实现仅在签名基本字符串中包含表单编码的正文参数。这是 OAuth 1.0 中的正确行为,但在后来的版本中得到了纠正。尝试发出不带正文的 PUT 请求,看看是否有帮助。如果确实如此,您将需要要求服务器库维护人员修复此问题或限制您的调用在使用 put 时不包含表单编码的正文。

Some OAuth server implementations only include form-encoded body parameters in the signature base string when the HTTP method is POST. This was the right behavior in OAuth 1.0 but was corrected in later revisions. Try making a PUT request without a body and see if that helps. If it does, you will need to ask the server library maintainer to fix this or limit your calls not to include a form-encoded body when using a put.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文