php - Keycloak无法从本地php服务器授权客户端,但使用邮递员时返回ok
问题描述
我已经设置了本地 php 服务器并想从 keycloak 获取授权令牌。
我已经发送了这样的请求:
$url = "http://docker:10040/auth/realms/myrealm/protocol/openid-connect/token"
$data = "client_id=postman&username=admin&password=12345&grant_type=password"
$headers = array('Content-Type: application/x-www-form-urlencoded');
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_VERBOSE, 1);
$result = curl_exec($curl);
但这返回给我:
{"error":"unauthorized_client","error_description":"Client secret not provided in request"}
现在,这显然是“你没有这样的客户”的情况,对吧?除非我使用邮递员“基本上”发送相同的请求:
POST /auth/realms/myrealm/protocol/openid-connect/token? HTTP/1.1
Host: docker:10040
Content-Type: application/x-www-form-urlencoded
cache-control: no-cache
Postman-Token: c08c2144-4ea0-45ad-ab16-150db7768825
最后一行是正文,但它不可读,所以让我们改写一下:
grant_type:password
username:admin
password:12345
client_id:postman
如您所见,基本相同。除了邮递员令牌。
邮递员的结果是包含 access_token 的正确答案:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxWjZ0SXNXa2JLSUNkSG96eWJHT1QybU90S1p1T3RiMU9lNWVRTlZzLW5ZIn0.eyJqdGkiOiI0OWE2MmE4Ny1lMjc2LTRjMjctODA5YS1jMTUzMWViNjYzOWQiLCJleHAiOjE1NTI0MDE1NjMsIm5iZiI6MCwiaWF0IjoxNTUyNDAxMjYzLCJpc3MiOiJodHRwOi8vZG9ja2VyOjEwMDQwL2F1dGgvcmVhbG1zLzFzcGlubWlsbGlvbmFpcmUiLCJhdWQiOiJwb3N0bWFuIiwic3ViIjoiMjFlMjc5MmEtNGQ1NS00YTVjLTlmNDctNDcxMDA5ZTEzNmFiIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoicG9zdG1hbiIsImF1dGhfdGltZSI6MCwic2Vzc2lvbl9zdGF0ZSI6ImU0MjY4YjQ3LWQzZjctNDQxMS1iYmY3LWM4MzE5OTUwZWE2OSIsImFjciI6IjEiLCJjbGllbnRfc2Vzc2lvbiI6IjFmMzhkYmE5LWRhYWMtNGUyOC1hODdjLTI4MDcyN2YzYzhjNSIsImFsbG93ZWQtb3JpZ2lucyI6W10sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJyb2xlX2FkbWluIiwicm9sZV92aWV3X3VzZXJzIiwicm9sZV9wYXJ0bmVyIiwidW1hX2F1dGhvcml6YXRpb24iLCJyb2xlX3BhcnRuZXJfYWRtaW5pc3RyYXRvciJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InJlYWxtLW1hbmFnZW1lbnQiOnsicm9sZXMiOlsidmlldy11c2VycyJdfSwicmVzb3VyY2Utc2VydmVyIjp7InJvbGVzIjpbInJvbGVfYWRtaW4iLCJyb2xlX3BhcnRuZXIiLCJyb2xlX3BhcnRuZXJfYWRtaW5pc3RyYXRvciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfX0sIm5hbWUiOiIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.Ojw34yZkNmeTBvD7M1OTLv5PRnPcNO7nxf5d_w8yh_zuGTXCwPEyKm1blfpBDYkrKtjbwnamwWWZeBKYzLCUwebnE5rrEDG13fKC3iTdqkh5tEYMRhn8C8LAGBPy6uVhWJyL2X9CCbNQNNTiBUD3Ida6EK1K0rreoSpWInHgEktBumpleFdznCUHoZe6-xina5S4yC1TtZOWtSl4nrBgrn720uqmg-lN6_HacV6YnldYmtJWr_ay7EvmTAc4KLh5XU6YyulcXrq7Z921Zqupe3VJRhhFNssWYqT7c_bIGao5HYTgcmOnRsp_iGuT_6ku2LFEKXrLxmVJDaM9ok_3lA",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxWjZ0SXNXa2JLSUNkSG96eWJHT1QybU90S1p1T3RiMU9lNWVRTlZzLW5ZIn0.eyJqdGkiOiIyOTJhMTY4NC1jZjk1LTRkYmMtYjdhNy1iM2RhZTZlY2NlODciLCJleHAiOjE1NTI0MDMwNjMsIm5iZiI6MCwiaWF0IjoxNTUyNDAxMjYzLCJpc3MiOiJodHRwOi8vZG9ja2VyOjEwMDQwL2F1dGgvcmVhbG1zLzFzcGlubWlsbGlvbmFpcmUiLCJhdWQiOiJwb3N0bWFuIiwic3ViIjoiMjFlMjc5MmEtNGQ1NS00YTVjLTlmNDctNDcxMDA5ZTEzNmFiIiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InBvc3RtYW4iLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJlNDI2OGI0Ny1kM2Y3LTQ0MTEtYmJmNy1jODMxOTk1MGVhNjkiLCJjbGllbnRfc2Vzc2lvbiI6IjFmMzhkYmE5LWRhYWMtNGUyOC1hODdjLTI4MDcyN2YzYzhjNSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJyb2xlX2FkbWluIiwicm9sZV92aWV3X3VzZXJzIiwicm9sZV9wYXJ0bmVyIiwidW1hX2F1dGhvcml6YXRpb24iLCJyb2xlX3BhcnRuZXJfYWRtaW5pc3RyYXRvciJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InJlYWxtLW1hbmFnZW1lbnQiOnsicm9sZXMiOlsidmlldy11c2VycyJdfSwicmVzb3VyY2Utc2VydmVyIjp7InJvbGVzIjpbInJvbGVfYWRtaW4iLCJyb2xlX3BhcnRuZXIiLCJyb2xlX3BhcnRuZXJfYWRtaW5pc3RyYXRvciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfX19.UTqGzJEnwzjsYnAIGvFafyJCWpmjVMjttvByX7r-KGtgmiqeKvVFSnisAIic8S8n6lHvAtW_K3s35CWovofHJqia9kEk2eyNZIZQGDM8LCum2KgKBOv4Jqg8H3F54gQzr4Pd17SbavpU38--FqDOHMX8a6L6GLs7yUy7PZ86MTm-B4V49ckleCGt0qMtzXMn8GmA1PnjCk5VpB_XR2FSEzuGfFwiXtq3HmWEGL-EybGRj-1GVNi568N2O1tKrHu8SeM-cg8KHEs5oa_C_lpCTii0OqVx7-NInaPpabua1QjrVtPtqS2f1dXuSMmVNwFRPw8ANHxmK4U9zFLgkBloxg",
"token_type": "bearer",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxWjZ0SXNXa2JLSUNkSG96eWJHT1QybU90S1p1T3RiMU9lNWVRTlZzLW5ZIn0.eyJqdGkiOiIyMGY1OTgzMC05MTFiLTQwNTctYWFiMi05N2NiZGJhNDEwNDMiLCJleHAiOjE1NTI0MDE1NjMsIm5iZiI6MCwiaWF0IjoxNTUyNDAxMjYzLCJpc3MiOiJodHRwOi8vZG9ja2VyOjEwMDQwL2F1dGgvcmVhbG1zLzFzcGlubWlsbGlvbmFpcmUiLCJhdWQiOiJwb3N0bWFuIiwic3ViIjoiMjFlMjc5MmEtNGQ1NS00YTVjLTlmNDctNDcxMDA5ZTEzNmFiIiwidHlwIjoiSUQiLCJhenAiOiJwb3N0bWFuIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiZTQyNjhiNDctZDNmNy00NDExLWJiZjctYzgzMTk5NTBlYTY5IiwiYWNyIjoiMSIsIm5hbWUiOiIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.tf1erOZwlXfIklEfx-RtHQvFA4ioMrgZUQYup1sPDQvrZIJJlUf_S6TtJXb226xLWHpyrBKiX6BHJmq6wKCNdOHwP1Rzr7toA7AdfqtRUtTpvW5ZyfzJod4u3wd55u6W5GFCfHPnaOrNEVexKT8HIEty35l110iX2eOAzVB9JBJ5OsJl9PkJzrAct3DhIchaqwWKPrVD2kebyRVNk4RlNJmRzDsH1br4Wv2F9Tjny5ShffzBbCn47LZDQBOO4VbcGgmzyrpYJ70l1DSChdL3chVihwPttA6kiQUYCux1wQd5MSue8Yu7u-YZbXXswOy9ZXU3mfWDdN2I1u4wX3T7UA",
"not-before-policy": 0,
"session_state": "e4268b47-d3f7-4411-bbf7-c8319950ea69"
}
我错过了什么?在我看来,它们看起来一样。主要区别显然是一种是通过邮递员/客户端发送,而另一种是通过基于服务器的 php 脚本发送。我看不出有问题的可能性。我错了吗?
如何通过 php 将 curl 发送到 keycloak 以便它返回给我访问令牌?
解决方案
有两种选择:
- 在访问类型组合框中(在客户端设置中)将客户端设置更改为公开而不是“机密”
在请求中添加参数,如:
&grant_type=password&client_secret=your_secret_client_value
推荐阅读
- css - 类属性未被继承
- android - ConnectivityManager connMgr = (ConnectivityManager) getContext().getSystemService 在加载时返回 null
- r - Set.seed() 结合 for 循环
- tensorflow - 当我连接两种神经网络时,我应该对分布进行归一化吗
- python - 从后端的单词列表中生成一个随机单词并将其显示在前端
- asp.net - 如何使用asp.net + vb.net从数据库列中获取数据并显示在下拉列表中
- angular - @types/applicationinsights-js 的 typescript 编译器问题
- css - 为一行中的元素设置间距
- unity3d - Unity Panel 无法正确适配屏幕
- python-3.x - 没有循环时如何通过停止迭代。