代码流Keycloak出现无效授予错误

问题描述 投票:0回答:1

我使用此命令在 docker 容器中运行 keycloak(我也尝试过版本 24)

docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:23.0 start-dev

当我访问该网址时

http://localhost:8080/realms/my_app/protocol/openid-connect/auth?response_type=code&scope=openid&redirect_uri=https://www.google.com/&client_id=my_app

在我使用邮递员发出获取令牌的请求后立即获得授权码

curl -X POST \
  http://localhost:8080/realms/my_app/protocol/openid-connect/token \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code' \
  -d 'client_id=my_app' \
  -d 'redirect_uri=https://www.google.com/' \
  -d 'code= {codeFromUrlEntered}'

但是我不断收到错误:

error="invalid_code", grant_type="authorization_code", code_id="594c3aa2-cec6-488d-8026-24b9fb6721e5", client_auth_method="client-secret"

我第一次使用授权码就可以确认。

docker security oauth-2.0 keycloak
1个回答
0
投票

看来配置中存在一些误解。

#1 领域和客户端 ID 之间似乎存在混淆。您已将 client_id 设置为 my_app,它实际上指的是 URL http://localhost:8080/realms/my_app 中的领域。 client_id 应对应于客户端标识符,而不是领域名称。

#2 redirect_uri 已设置为 https://www.google.com/。为了安全性和功能性,redirect_uri 应与本地服务器或生产环境的 URL 一致,而不是与 google.com 等不相关的网站一致。

#3 授权代码流程(grant_type=authorization_code)需要用户登录步骤;因此,直接使用 cURL 来完成此过程是不可行的。此流程需要提供本地服务器来通过重定向 URL 处理代码交换。

演示

启动钥匙斗篷

docker compose
这里

设置领域/客户端

领域:

my_app

客户:

my_client

客户秘密

创建用户

凭证

username: user1
password: 1234

获取代币URL

"authorization_endpoint": "http://localhost:8080/realms/my_app/protocol/openid-connect/auth",
"token_endpoint": "http://localhost:8080/realms/my_app/protocol/openid-connect/token",

服务器

另存为

server.js

const express = require('express');
const axios = require('axios');

const app = express();
const port = 3000;

const KEYCLOAK_CLIENT_ID = "my_client";
const KEYCLOAK_CLIENT_SECRET = "oCDrud4nUSxp6ol56u9ZEJhdG3tsKji9"; // your client secret
const KEYCLOAK_REALM = "my_app";
const KEYCLOAK_SERVER_URL = "http://localhost:8080";
const REDIRECT_URI = "http://localhost:3000/callback"; // your client's redirect URI

app.get('/login', (req, res) => {
  const authUrl = `${KEYCLOAK_SERVER_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/auth?client_id=${encodeURIComponent(KEYCLOAK_CLIENT_ID)}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&response_type=code&scope=openid`;
  res.redirect(authUrl);
});

app.get('/callback', async (req, res) => {
  const { code } = req.query;
  try {
    const response = await axios.post(`${KEYCLOAK_SERVER_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token`, new URLSearchParams({
      client_id: KEYCLOAK_CLIENT_ID,
      client_secret: KEYCLOAK_CLIENT_SECRET,
      redirect_uri: REDIRECT_URI,
      grant_type: 'authorization_code',
      code,
    }), {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    });

    const { access_token, refresh_token, id_token } = response.data;
    // Here you can store/use the tokens as needed
    res.json({ access_token, refresh_token, id_token });
  } catch (error) {
    res.status(500).json({ error: error.toString() });
  }
});

app.listen(port, () => {
  console.log(`Server listening at http://localhost:${port}`);
});

安装依赖项

npm install express axios

运行服务器

node server.js

用户登录

打开浏览器并访问此 URL。

http://localhost:3000/login

凭证

username: user1
password: 1234

结果

将在浏览器中显示令牌

© www.soinside.com 2019 - 2024. All rights reserved.