OAuth2 (Okta) 令牌生成失败并出现 401 未经授权的响应 - client_credentials 授予类型

发布于 2025-01-15 08:37:01 字数 1943 浏览 1 评论 0原文

我在尝试获取 OAuth2 (Okta) 令牌时遇到了 AJAX 请求失败并出现错误代码 401 - 未经授权的问题。

预览选项卡显示错误,如下所示:

Browser requests to the token endpoint must use Proof Key for Code Exchange

这是否意味着我无法将 client_credentials 授予类型用于客户端请求?

这是我的 AJAX 请求:

$.ajax({
    url: dataParsed.TokenServiceEndpoint,
    type: "POST",
    contentType: "application/x-www-form-urlencoded",
    datatype: "application/json",
    headers: {
        "Authorization": "Basic " + btoa(dataParsed.TokenServiceUser + ":" + dataParsed.TokenServicePassword)
    },
    data: {
        "grant_type": "client_credentials"
    }
}

类似的请求使用邮递员工作,但我不确定两者之间有什么区别,或者如何使其通过 ajax 工作。

这是从 Postman 导出的请求:

Content-Type: application/x-www-form-urlencoded
Authorization: Basic *************
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: fd2c4617-a4bb-4d28-88bd-1aa84c2a7404
Host: *****
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 29
Cookie: JSESSIONID=3B62F82EE85BC8574756101635CC3B14
 
grant_type=client_credentials
 
HTTP/1.1 200 OK
Date: Fri, 18 Mar 2022 14:41:42 GMT
Server: nginx
Content-Type: application/json
x-okta-request-id: YjSaJqln-TB3pOn9kgwmsQAABSw
x-xss-protection: 0
p3p: CP="HONK"
x-rate-limit-limit: 20000
x-rate-limit-remaining: 19971
x-rate-limit-reset: 1647614537
cache-control: no-cache, no-store
pragma: no-cache
expires: 0
expect-ct: report-uri="*****", max-age=0
x-content-type-options: nosniff
Strict-Transport-Security: max-age=315360000; includeSubDomains
X-Robots-Tag: noindex,nofollow
set-cookie: sid=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
set-cookie: autolaunch_triggered=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
set-cookie: JSESSIONID=AA2D48FFC46A8AC0E1D139D038CE98AB; Path=/; Secure; HttpOnly
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked

I ran into a problem where my AJAX request fails with error code 401 - Unauthorized, while trying to get an OAuth2 (Okta) Token.

The preview tab shows an error as follows:

Browser requests to the token endpoint must use Proof Key for Code Exchange

Does this mean I can't use the client_credentials grant type for client side requests?

Here is my AJAX request:

$.ajax({
    url: dataParsed.TokenServiceEndpoint,
    type: "POST",
    contentType: "application/x-www-form-urlencoded",
    datatype: "application/json",
    headers: {
        "Authorization": "Basic " + btoa(dataParsed.TokenServiceUser + ":" + dataParsed.TokenServicePassword)
    },
    data: {
        "grant_type": "client_credentials"
    }
}

A similar request works using postman, but I am not sure what the difference is between the two, or how to make it work through ajax.

Here is the request exported from Postman:

Content-Type: application/x-www-form-urlencoded
Authorization: Basic *************
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: fd2c4617-a4bb-4d28-88bd-1aa84c2a7404
Host: *****
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 29
Cookie: JSESSIONID=3B62F82EE85BC8574756101635CC3B14
 
grant_type=client_credentials
 
HTTP/1.1 200 OK
Date: Fri, 18 Mar 2022 14:41:42 GMT
Server: nginx
Content-Type: application/json
x-okta-request-id: YjSaJqln-TB3pOn9kgwmsQAABSw
x-xss-protection: 0
p3p: CP="HONK"
x-rate-limit-limit: 20000
x-rate-limit-remaining: 19971
x-rate-limit-reset: 1647614537
cache-control: no-cache, no-store
pragma: no-cache
expires: 0
expect-ct: report-uri="*****", max-age=0
x-content-type-options: nosniff
Strict-Transport-Security: max-age=315360000; includeSubDomains
X-Robots-Tag: noindex,nofollow
set-cookie: sid=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
set-cookie: autolaunch_triggered=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
set-cookie: JSESSIONID=AA2D48FFC46A8AC0E1D139D038CE98AB; Path=/; Secure; HttpOnly
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked

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

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

发布评论

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

评论(2

合约呢 2025-01-22 08:37:01

客户端凭据授予用于服务器到服务器的通信。它允许您的客户端在授权服务器上进行身份验证以获得访问令牌。这意味着您需要一个机密客户端才能成功使用此流程 - 一个拥有秘密并可以使用该秘密进行身份验证的客户端。浏览器客户端(例如 SPA)无法保存秘密 - 任何人都可以从您的代码中读取秘密。这就是 Okta 不允许您直接从浏览器使用客户端凭据的原因。错误响应告诉您浏览器客户端必须使用 PKCE,并且由于 PKCE 只能在授权代码流中使用,这隐含意味着 Okta 仅允许来自浏览器客户端的授权代码流。

邮递员不是浏览器,这就是邮递员的请求起作用的原因。如果您从curl 运行它,它也会起作用。

总而言之,您不必使用浏览器中的客户端凭据。如果您仅需要它用于开发目的或解决问题,您可以从邮递员运行流程并将令牌粘贴到前端代码中。在生产代码中,您应该使用授权代码流程。但您应该记住,此流程需要用户交互。

Client credentials grant is meant for server-to-server communication. It allows your client to authenticate at the Authorization Server to get an access token. This means that you need a confidential client to successfully use this flow - a client which holds a secret and can authenticate using that secret. A browser client (e.g. an SPA), can't hold secrets - anyone is able to read the secret from your code. That's why Okta doesn't let you use client credentials directly from the browser. The error response tells you that browser clients must use PKCE, and as PKCE is only possible in an authorization code flow, this implicitly means that Okta allows only authorization code flow from a browser client.

Postman is not a browser, that's why the request from postman works. It will also work if you run it from curl.

All in all, you shouldn't have to use client credentials from your browser. If you need it just for development purposes or figuring things out, you can run the flow from postman and paste the token into your frontend code. In a production code, you should use authorization code flow. You should remember, though, that this flow requires user interaction.

赠我空喜 2025-01-22 08:37:01

使用 Fiddler 跟踪您的请求,Okta 也不支持浏览器中的客户端凭据,必须位于服务器级别。
检查此 - https://support.okta.com/help/s/article/Browser-requests-to-the-token-endpoint-must-use-Proof-Key-for-Code-Exchange?language=en_US

我说使用 Fiddler 进行跟踪的原因是,您可以在使用 postman 与 ajax 时确认是否发送了原始标头,因此,确认您是否遇到了我粘贴的链接中提到的问题。

Trace your request with Fiddler, also client side client credentials is not supported by Okta from browser, has to be at server level.
Check this - https://support.okta.com/help/s/article/Browser-requests-to-the-token-endpoint-must-use-Proof-Key-for-Code-Exchange?language=en_US

The reason I said to trace with Fiddler is so that you can confirm if origin header is being sent or not when using postman vs from ajax and therefore, confirm that you are running into the issue mentioned in the link I pasted.

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