0

我一直在关注本指南,了解如何使用 Keycloak 保护我的 JAX-RS API。我正在执行它提供的所有步骤,但遗憾的是我无法让我的身份验证正常工作。我的请求总是导致 401 响应。我希望你们中的一些人可以帮助我解决这个问题。

我使用 docker-compose 来运行所有容器。

docker-compose.yaml

version: '3'

services:
  products:
    image: maven:alpine
    volumes:
      - ./products/target/:/usr/src/products
    command: java -jar /usr/src/products/products-0.0.1.jar
    environment:
      MYSQL_USER: mysql
      MYSQL_PASS: mysql
    ports:
      - 8000:8080
    networks:
      - keycloak

  keycloak:
    image: jboss/keycloak
    environment:
      KEYCLOAK_USER: keycloak
      KEYCLOAK_PASSWORD: keycloak
      DB_VENDOR: postgres
      DB_ADDR: keycloakDb
      DB_USER: keycloak
      DB_PASSWORD: password
    ports:
      - 8100:8080
    depends_on:
      - keycloakDb
    networks:
      - keycloak

  keycloakDb:
    image: postgres
    volumes:
      - ./volumes/keycloak/data:/var/lib/postgresql
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: password
    networks:
      - keycloak

networks:
  keycloak:
    driver: bridge

我使用这些设置来配置 Kumuluz

config.yaml

kumuluzee:
  security:
    keycloak:
      json: '{
               "realm": "producerstore-realm",
               "bearer-only": true,
               "auth-server-url": "http://keycloak:8080/auth",
               "ssl-required": "external",
               "resource": "producerstore-api",
               "confidential-port": 0
             }'

这是我的 JAX-RS 应用程序和 REST 资源。

Api.java

@ApplicationPath("")
@DeclareRoles({"admin", "customer"})
public class Api extends Application {
}

ProductResource.java

@GET
@PermitAll
@Path("/products")
public Response getAll() {
    try {
        return Response.ok()
            .entity(service.getAll())
            .build();
    } catch (Exception e) {
        return internalServerError(e.getMessage());
    }
}

@POST
@RolesAllowed({"admin"})
@Path("/products")
public Response createProduct(ProductDto productDto, @Context UriInfo uriInfo) {
    try {
        long createdId = service.add(productDto);

        URI uri = uriInfo.getAbsolutePathBuilder()
                            .segment(Long.toString(createdId))
                            .build();

        return Response.created(uri)
            .build();
    } catch (CreationException e) {
        return internalServerError(e.getMessage());
    }
}

我还在 Keycloak 中定义了管理员和客户角色。接下来,我创建了一个用户并将这些角色分配给他们。

当我使用该用户登录时,我会收到正确的 JWT。

curl -X POST \
  http://localhost:8100/auth/realms/producerstore-realm/protocol/openid-connect/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=password&client_id=producerstore-app&username=<username>&password=<password>'

这导致以下标记

{
    "access_token": "<very-long-token>",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "<another-very-long-token>",
    "token_type": "bearer",
    "not-before-policy": 0,
    "session_state": "770908df-08fa-4935-8666-a58ae41447e7",
    "scope": "profile email"
}

但是当我尝试请求我的资源时,它总是会导致 401。

curl -X GET \
  http://localhost:8000/products \
  -H 'Authorization: Bearer <very-long-token>'
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
        <title>Error 401 Unauthorized</title>
    </head>
    <body>
        <h2>HTTP ERROR 401</h2>
        <p>Problem accessing /products. Reason:

            <pre>    Unauthorized</pre>
        </p>
        <hr>
        <a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.15.v20190215</a>
        <hr/>
    </body>
</html>

我希望你们中的一些人可以帮助我解决这个问题,如果您需要更多关于某些事情的信息,我会很乐意提供。

谢谢!

4

1 回答 1

0

我相当有信心令牌颁发者 URL 与配置中的领域 URL 不匹配。尝试使用以下 keycloak docker-compose.yml 配置:

version: '3'

keycloak:
    image: jboss/keycloak
    environment:
      KEYCLOAK_USER: keycloak
      KEYCLOAK_PASSWORD: keycloak
      KEYCLOAK_HOSTNAME: keycloak
      DB_VENDOR: postgres
      DB_ADDR: keycloakDb
      DB_USER: keycloak
      DB_PASSWORD: password
    ports:
      - 8080:8080
    depends_on:
      - keycloakDb
    networks:
      - keycloak

keycloak映射添加到您的主机文件,以便您keycloak在 docker 外部访问。

于 2019-06-23T10:36:23.810 回答