微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – Docker(Spring Boot或Thorntail)和Keycloak

我在Docker容器中运行Spring Boot和Keycloak时出现问题.

我开始使用Keycloak和MysqL作为db在docker中运行.

services:
  MysqL:
    image: MysqL:5.7
    container_name: MysqL
    volumes:
      - MysqL_data:/var/lib/MysqL
    environment:
      MysqL_ROOT_PASSWORD: root
      MysqL_DATABASE: keycloak
      MysqL_USER: keycloak
      MysqL_PASSWORD: password
    networks:
      - testNetwork

  keycloak:
    image: jboss/keycloak
    container_name: keycloak
    restart: on-failure
    volumes:
      - ./config:/config/
    environment:
      DB_vendOR: MysqL
      DB_ADDR: MysqL
      DB_DATABASE: keycloak
      DB_USER: keycloak
      DB_PASSWORD: password
      KEYCLOAK_USER: xxx
      KEYCLOAK_PASSWORD: yyy
      KEYCLOAK_IMPORT_REALM: /keycloak/import/realm-import.json
    ports:
      - 8180:8080
    depends_on:
      - MysqL
    networks:
      - testNetwork

然后我添加了我的领域(SpringBootKeycloak),我的客户端(testclient)和一个角色为’user’的用户.
之后,我在Spring-boot-application中添加了spring-security.并编辑了我的application.yml

spring:
  main:
    banner-mode: 'off'
  application:
    name: testclient
    version: @project.version@
  jpa:
    hibernate:
      ddl-auto: create
  datasource:
    url: jdbc:h2:mem:testclient;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
    username: xxx
    password: xxx
keycloak:
  auth-server-url: http://localhost:8180/auth
  realm: SpringBootKeycloak
  resource: testclient
  public-client: true
  principal-attribute: preferred_username
  security-constraints:
    - authRoles:
      - user
      securityCollections:
        - patterns:
          - /*
server:
  port: ${port:8090}
  rest:
    path: testclient

因为我添加了我的SecurityConfig

  /**
   * Secure appropriate endpoints
   */
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);
    http.authorizeRequests()
        .antMatchers("/*").hasRole("user") // only user with role user are allowed to access
        .anyRequest().permitAll();
  }

在本地运行我的SpringBoot-Application工作正常.
我必须使用keycloak登录重定向到localhost:8090.
但是当我将我的SpringBoot-Application添加到我的docker-compose并在容器中启动时,我仍然可以使用keycloak进行登录,但是当我应该重定向时,我得到403.

  testclient:
    image: testclient
    container_name: testclient
    environment:
      JAVA_OPTS: "-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n"
    build:
      context: testclient-application
    ports:
      - 8090:8090
      - 5006:5005
    networks:
      - testNetwork

使用以下容器日志:

{"@timestamp":"2018-08-16T11:50:11.530+00:00","@version":"1","message":"Failed to turn code into token","logger_name":"org.keycloak.adapters.OAuthRequestAuthenticator","thread_name":"http-nio-8090-exec-6","level":"ERROR","level_value":40000,"stack_trace":"java.net.ConnectException: Connection refused (Connection refused)\n\tat java.net.PlainSocketImpl.socketConnect(Native Method)\n\tat java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)\n\tat java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)\n\tat java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)\n\tat java.net.socksSocketImpl.connect(SocksSocketImpl.java:392)\n\tat java.net.socket.connect(Socket.java:589)\n\tat org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)\n\tat org.apache.http.impl.conn.DefaultClientConnectionoperator.openConnection(DefaultClientConnectionoperator.java:180)\n\tat org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144)\n\tat org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134)\n\tat org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610)\n\tat org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445)\n\tat org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835)\n\tat org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)\n\tat org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)\n\tat org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)\n\tat org.keycloak.adapters.ServerRequest.invokeAccessCodetoToken(ServerRequest.java:111)\n\tat org.keycloak.adapters.OAuthRequestAuthenticator.resolveCode(OAuthRequestAuthenticator.java:336)\n\tat org.keycloak.adapters.OAuthRequestAuthenticator.authenticate(OAuthRequestAuthenticator.java:281)\n\tat org.keycloak.adapters.RequestAuthenticator.authenticate(RequestAuthenticator.java:139)\n\tat org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.authenticateInternal(AbstractKeycloakAuthenticatorValve.java:203)\n\tat org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve.authenticate(KeycloakAuthenticatorValve.java:50)\n\tat org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve.doAuthenticate(KeycloakAuthenticatorValve.java:57)\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:575)\n\tat org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181)\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)\n\tat org.apache.tomcat.util.net.socketProcessorBase.run(SocketProcessorBase.java:49)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\n\tat java.lang.Thread.run(Thread.java:748)\n","app":"testclient","version":"1.0.0-SNAPSHOT"}

我无法弄清楚如何解决这个问题……

编辑1:
还有一个信息:我在Windows上运行docker.

编辑2:解决方

我的工作解决方案包含以

>步骤,添加keycloak作为主机

To make things work, you’ll need to make sure to add the following to your hosts file (/etc/hosts on Mac/Linux, c:\Windows\System32\Drivers\etc\hosts on Windows).

127.0.0.1 keycloak

This is because you will access your application with a browser on your machine (which name is localhost, or 127.0.0.1), but inside Docker it will run in its own container, which name is keycloak.

>一步

内部Docker端口和发布端口需要相同:

services:
  MysqL:
    image: MysqL:5.7
    container_name: MysqL
    volumes:
      - MysqL_data:/var/lib/MysqL
    environment:
      MysqL_ROOT_PASSWORD: root
      MysqL_DATABASE: keycloak
      MysqL_USER: keycloak
      MysqL_PASSWORD: password
    networks:
      - testNetwork

  keycloak:
    image: jboss/keycloak
    container_name: keycloak
    restart: on-failure
    volumes:
      - ./config:/config/
    environment:
      DB_vendOR: MysqL
      DB_ADDR: MysqL
      DB_DATABASE: keycloak
      DB_USER: keycloak
      DB_PASSWORD: password
      KEYCLOAK_USER: xxx
      KEYCLOAK_PASSWORD: yyy
      KEYCLOAK_IMPORT_REALM: /keycloak/import/realm-import.json
    ports:
      - 8080:8080   <--- edited
    depends_on:
      - MysqL
    networks:
      - testNetwork

第3步:application.yml中的keycloak定义,用于Spring启动编辑的auth-server-url:

    keycloak:
  realm: SpringBootKeycloak
  auth-server-url: http://keycloak:8080/auth   <--- edited
  resource: testclient
  public-client: true
  security-constraints:
    - authRoles:
      - user
      securityCollections:
        - patterns:
          - /*
  ssl-required: external
  confidential-port: 0

这个解决方案带来了丑陋的事情:
您无法将Docker端口映射到另一个端口以从URL访问.
  端口:
     – 8080:8080
我花了很多时间测试其他组合,结果是访问URL端口必须与内部docker端口相同(在我的情况下为8080).

编辑4:

同样的事情是与thorntail合作.

要更改Keycloak添加的端口…

environment:
  JAVA_OPTS: "-Djboss.socket.binding.port-offset=10 -xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m
  -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true"

…对于docker-compose中的keycloak.
-Djboss.socket.binding.port-offset = 10设置认端口(8080)偏移量(10)
其余是keycloak的认值.
别忘了编辑“ports”和“auth-server-url”

解决方法:

我认为您的问题是auth-server-url:http:// localhost:8180 / auth.当您的应用程序在docker容器中运行时,localhost实际上具有不同的含义.

在容器内部,它需要是容器的名称,即keycloak.这有点尴尬,因为当您从主机连接到keycloak时,您想要使用localhost,但令牌发行者url需要匹配请求令牌的URL(否则令牌被拒绝),所以你最终必须将keycloak放入etc / hosts文件中.

你和这个问题很好 – 我遇到了这个working with Activiti.你可以找到JHipster project dealing with it in the same way – 他们说:

To make things work, you’ll need to make sure to add the following to your hosts file (/etc/hosts on Mac/Linux, c:\Windows\System32\Drivers\etc\hosts on Windows).

127.0.0.1 keycloak

This is because you will access your application with a browser on your machine (which name is localhost, or 127.0.0.1), but inside Docker it will run in its own container, which name is keycloak.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐