0

我遇到了一个关于 docker 的问题,我最近一直在努力解决这个问题。这是故事的简化版本

在我的开发环境中(一切都在本地主机上运行),代码运行良好,每当我在我的标头中添加我的授权令牌时,keycloak-connect 都会检测到它并照常工作。当我在 docker 中使用它并添加自定义网络接口时会出现问题。

当 docker 容器启动时,我让它通过 http://keycloak:8080/auth 连接到 keycloak 并生成领域。这工作正常,不是问题,因此我知道 keycloak 网络已按预期启动并运行。我能够远程进入容器,与 keycloak 通信,获取令牌等等......

在我的 graphql 应用程序中,我使用 keycloak-connect-graphql 设置 graphql 应用程序的上下文,该应用程序又使用 keycloak-connect 设置所有标题。问题是,那个keycloak-connect-graphql告诉我没有header。如果我简单的打印出请求,我可以清楚的知道有一个token被传入,只是由于某种原因,keycloak-connect- graphql/keycloak-connect 不想设置它,因为我使用的是除 localhost 之外的不同网络。

实际上,我可以通过将 keycloak url 设置为公共 url ( https://keycloak.DOMAINNAME.com ) 在生产中避开这个问题,这对我来说完全没有意义,因为 http://keycloak:8080/身份验证不起作用。我已经深入研究了 keycloak-connect 和 keycloak-connect-graphql 代码,但找不到与 CORS 问题或其他可疑问题相关的任何内容。如果有人有任何想法,请告诉我。这个错误一直让我发疯。

代码片段:keycloak 配置 (app.config)

  keycloak: {
    realm: process.env.KEYCLOAK_REALM,
    'auth-server-url': 'http://keycloak:8080/auth',
    'ssl-required': 'none',
    resource: process.env.KEYCLOAK_RESOURCE,
    'public-client': true,
    'use-resource-role-mappings': true,
    'confidential-port': 0,
  },

配置keycloak.js

function configureKeycloak(app, graphqlPath) {
  const keycloakConfig = require('../config/app.config').keycloak;

  const memoryStore = new session.MemoryStore();

  app.use(
    session({
      secret:
        process.env.SESSION_SECRET_STRING || 'this should be a long secret',
      resave: false,
      saveUninitialized: true,
      store: memoryStore,
    }),
  );

  const keycloak = new Keycloak(
    {
      store: memoryStore,
    },
    keycloakConfig,
  );

  // Install general keycloak middleware
  app.use(
    keycloak.middleware({
      admin: graphqlPath,
    }),
  );

  // Protect the main route for all graphql services
  // Disable unauthenticated access
  app.use(graphqlPath, keycloak.middleware());

  return { keycloak };
}

index.js

// perform the standard keycloak-connect middleware setup on our app
const { keycloak } = configureKeycloak(app, graphqlPath);

// Ensure entire GraphQL Api can only be accessed by authenticated users
app.use(playgroundPath, keycloak.protect());

const server = new ApolloServer({
  gateway,
  // uploads: false,

  // Apollo Graph Manager (previously known as Apollo Engine)
  // When enabled and an `ENGINE_API_KEY` is set in the environment,
  // provides metrics, schema management and trace reporting.
  engine: false,

  // Subscriptions are unsupported but planned for a future Gateway version.
  subscriptions: false,

  // Disable default playground
  playground: true,

  context: ({ req }) => {
    return {
      kauth: new KeycloakContext({ req }),
    };
  },

  // Tracing must be enabled for this plugin to add the headers
  tracing: true,
  // Register the plugin
  plugins: [ServerTimingPlugin],
});

编辑:将network_mode设置为host解决了这个问题,但我更喜欢使用dockers集成网络而不是使用network_mode主机,特别是对于生产

编辑 2:我能够在我的本地开发环境中重现该错误(无需进入 docker,然后从那里进行调试)。我可以使用 docker 提供的 IP 地址进行购买。这会产生相同的结果。我已将问题缩小到 keycloak-connect,由于某种原因,它不想连接到 keycloak 或其他东西。仍然不确定

4

0 回答 0