Настройка Policy Enforcer в Keycloak - PullRequest
0 голосов
/ 26 мая 2020

Я новичок в 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\"]"
                        }
                    }
                ]
            }
        }
    ]
}
  • 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]=/*
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-Вопрос: Может ли кто-нибудь объяснить мне описанный выше сценарий? Что мне не хватает для правильного поведения средства обеспечения соблюдения политики. Я застрял и не нахожу никакого решения, хотя следую инструкциям по быстрому запуску?

С уважением

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...