Я следовал этому руководству по защите моего JAX-RS API с помощью Keycloak. Я делаю все шаги, которые он предоставляет, но, к сожалению, я не могу заставить мою аутентификацию работать правильно. Мои запросы всегда приводят к ответу 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>'
Error 401 Unauthorized
HTTP ERROR 401
Problem accessing /products. Reason:
Unauthorized
Powered by Jetty: // 9.4.15.v20190215
<Ч />
Я надеюсь, что некоторые из вас могут помочь мне с этой проблемой, если вам нужна дополнительная информация о чем-то, я с радостью предоставлю ее.
Спасибо!