Я новичок в Keycloak, и я прохожу через быстрый запуск по ссылке: Quickstart
Цель:
- Проект просто предоставляет один Rest-API:
public class ApplicationController {
@RequestMapping(value = "/api/{employee}", method = RequestMethod.GET)
public Employee salary(@PathVariable String employee) {
return new Employee(employee);
}
public static class Employee {
private final String name;
public Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
- Api защищен с помощью служб авторизации: область, пользователи, роли, ресурсы, политики и разрешения импортируются с помощью следующего списка:
{
"realm": "spring-boot-quickstart",
"enabled": true,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [
"password"
],
"users": [
{
"username": "alice",
"enabled": true,
"credentials": [
{
"type": "password",
"value": "alice"
}
],
"realmRoles": [
"user"
]
},
{
"username": "jdoe",
"enabled": true,
"credentials": [
{
"type": "password",
"value": "jdoe"
}
],
"realmRoles": [
"user",
"people-manager"
]
},
{
"username": "service-account-app-authz-rest-employee",
"enabled": true,
"serviceAccountClientId": "app-authz-rest-employee",
"clientRoles": {
"app-authz-rest-employee": [
"uma_protection"
]
}
}
],
"roles": {
"realm": [
{
"name": "user",
"description": "User privileges"
},
{
"name": "people-manager",
"description": "People manager privileges"
}
]
},
"clients": [
{
"clientId": "app-authz-rest-employee",
"enabled": true,
"baseUrl": "http://localhost:8080",
"adminUrl": "http://localhost:8080",
"redirectUris": [
"http://localhost:8080/*"
],
"secret": "secret",
"directAccessGrantsEnabled": true,
"authorizationServicesEnabled": true,
"authorizationSettings": {
"allowRemoteResourceManagement": false,
"policyEnforcementMode": "ENFORCING",
"resources": [
{
"_id": "deed8ae3-41a9-4781-b6c7-cb297516c2c6",
"name": "Employee Resource",
"uri": "/api/{employee}/*"
}
],
"policies": [
{
"name": "Employee Policy",
"description": "A policy that enforces access based on the current user and requested path",
"type": "script-match-user-from-uri.js",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS"
},
{
"id": "15e7bbe5-34da-4f7f-9513-5ca0e09ca13e",
"name": "Only People Manager Policy",
"type": "role",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS",
"config": {
"roles": "[{\"id\":\"people-manager\",\"required\":false}]"
}
},
{
"id": "521b8081-5097-4264-af70-168f34c3b2a7",
"name": "Employee Permission",
"type": "resource",
"logic": "POSITIVE",
"decisionStrategy": "AFFIRMATIVE",
"config": {
"resources": "[\"Employee Resource\"]",
"applyPolicies": "[\"Only People Manager Policy\",\"Employee Policy\"]"
}
}
]
}
}
]
}
server.connection-timeout=5000
server.port = 8080
keycloak.realm=spring-boot-quickstart
keycloak.auth-server-url=http://localhost:8180/auth
keycloak.ssl-required=external
keycloak.resource=app-authz-rest-employee
keycloak.bearer-only=true
keycloak.credentials.secret=234d66af-58c7-4105-83cb-ea92c559a21f
keycloak.securityConstraints[0].authRoles[0]=user
keycloak.securityConstraints[0].securityCollections[0].name=protected
keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/*
keycloak.policy-enforcer-config.enforcement-mode=ENFORCING
keycloak.policy-enforcer-config.claimInformationPointConfig.claims[http.uri]={request.relativePath}
# Turn off the logs
logging.level.root=OFF
logging.level.org.springframework.boot=OFF
spring.main.banner-mode=OFF
1-Первый запрос у почтальона:
method=POST
url: http://localhost:8180/auth/realms/spring-boot-quickstart/protocol/openid-connect/token
client_id=app-authz-rest-employee
username=alice
password=alice
grant_type=password
client_secret=234d66af-58c7-4105-83cb-ea92c559a21f
Basic Auth used with:
username=alice
password=alice
В результате я получаю токен:
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGSjg2R2NGM2pUYk5MT2NvNE52WmtVQ0lVbWZZQ3FvcXRPUWVNZmJoTmxFIn0.eyJleHAiOjE1OTA0Nzg1MzIsImlhdCI6MTU5MDQ3ODIzMiwianRpIjoiYzQzMGI0MDYtZGY3ZS00Y2M0LTk1MjUtZjE2N2NlZjk4MGFmIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MTgwL2F1dGgvcmVhbG1zL3NwcmluZy1ib290LXF1aWNrc3RhcnQiLCJzdWIiOiI1ODkyMzdiNi00MDM4LTRkZDQtOTNmZS1jMGQ2ZTY5MWYyYjYiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhcHAtYXV0aHotcmVzdC1lbXBsb3llZSIsInNlc3Npb25fc3RhdGUiOiI2MDFiMTRmNy1kYzRiLTQ0NzAtOTFiNC02NmE3ZTJkMTQxOTUiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsidXNlciJdfSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhbGljZSJ9.nP2ZZU8PBqq88xhMVop-ELnI8TvmME9v5I9zbVwd9cRIMM5USbUj36J3_YoOcoKTcuwZCwnvKVMZXH0joZtzF72pFP57T_Ab75_PQfD3nWHzwuRoJAM1D7C3LYVLADdYgeFUBBG5aPheUNiAL2qIUOc1YuV5Yv_peuQDVlhw8VY
** Проблема **
2-секундный запрос у почтальона:
url: http://localhost:8080/api/alice/
Bearer Token:
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGSjg2R2NGM2pUYk5MT2NvNE52WmtVQ0lVbWZZQ3FvcXRPUWVNZmJoTmxFIn0.eyJleHAiOjE1OTA0Nzg1MzIsImlhdCI6MTU5MDQ3ODIzMiwianRpIjoiYzQzMGI0MDYtZGY3ZS00Y2M0LTk1MjUtZjE2N2NlZjk4MGFmIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MTgwL2F1dGgvcmVhbG1zL3NwcmluZy1ib290LXF1aWNrc3RhcnQiLCJzdWIiOiI1ODkyMzdiNi00MDM4LTRkZDQtOTNmZS1jMGQ2ZTY5MWYyYjYiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhcHAtYXV0aHotcmVzdC1lbXBsb3llZSIsInNlc3Npb25fc3RhdGUiOiI2MDFiMTRmNy1kYzRiLTQ0NzAtOTFiNC02NmE3ZTJkMTQxOTUiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsidXNlciJdfSwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhbGljZSJ9.nP2ZZU8PBqq88xhMVop-ELnI8TvmME9v5I9zbVwd9cRIMM5USbUj36J3_YoOcoKTcuwZCwnvKVMZXH0joZtzF72pFP57T_Ab75_PQfD3nWHzwuRoJAM1D7C3LYVLADdYgeFUBBG5aPheUNiAL2qIUOc1YuV5Yv_peuQDVlhw8VY
(«используется предыдущий полученный токен»)
Результат:
403 Запрещено
3-Изменить на application.properties : Удалив следующие 2 строки из исходного application.properties
keycloak.policy-enforcer-config.enforcement-mode=ENFORCING
keycloak.policy-enforcer-config.claimInformationPointConfig.claims[http.uri]={request.relativePath}
, результат станет следующим:
{
"timestamp": "2020-05-26T09:06:47.638+0000",
"status": 401,
"error": "Unauthorized",
"message": "No message available",
"path": "/api/alice/"
}
** и значение WWW-Authenticate это: **
Bearer realm="spring-boot-quickstart", error="invalid_token", error_description="Token is not active"
4-Замена значения в application.properties Когда я заменяю /*
на /**
и использую следующие application.properties:
server.connection-timeout=5000
server.port = 8080
keycloak.realm=spring-boot-quickstart
keycloak.auth-server-url=http://localhost:8180/auth
keycloak.ssl-required=external
keycloak.resource=app-authz-rest-employee
keycloak.bearer-only=true
keycloak.credentials.secret=234d66af-58c7-4105-83cb-ea92c559a21f
keycloak.securityConstraints[0].authRoles[0]=user
keycloak.securityConstraints[0].securityCollections[0].name=protected
keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/**
результат:
{
"name": "alice"
}
5-Вопрос: Может ли кто-нибудь объяснить мне описанный выше сценарий? Что мне не хватает для правильного поведения средства обеспечения соблюдения политики. Я застрял и не нахожу никакого решения, хотя следую инструкциям по быстрому запуску?
С уважением