JHipster не получает роли от пользователей Keycloak при входе в систему - PullRequest
0 голосов
/ 31 января 2019

У меня есть монолитное приложение JHipster с oauth2, работающее локально с Keycloak.Я не знаю, как именно jhipster должен работать с oauth2 ... Сначала я подумал, что он создаст пользователя автоматически, но это не так, поэтому я настроил keycloak: я создал область jhipster, клиент web_app,роли клиента ROLE_ADMIN и ROLE_USER и пользователи admin и user с их правильными ролями.Проблема в том, что когда я вхожу как администратор, он не распознается как ROLE_ADMIN, в результате я не могу получить доступ к меню администратора.Поэтому я начал просматривать код, пытаясь понять, как Jhipster получает учетные данные от Keycloak, и я понял, что объект OAuth2Authentication в AccountResource.java не приносит ROLE_ADMIN, а ROLE_USER, который я не получаюпонимаю почему.OAuth2Authentication объект в json выглядит следующим образом:

    {    
"authorities": [
        {
          "authority": "ROLE_USER"
        }
      ],
      "details": {
        "remoteAddress": "0:0:0:0:0:0:0:1",
        "sessionId": "rkkveY_Xa5zFFd0SKu9Of_FLGRnbdiTPHdnpj4gc",
        "tokenValue": "eyJhbGciOiJSUzI1...",
        "tokenType": "bearer",
        "decodedDetails": null
      },
      "authenticated": true,
      "userAuthentication": {
        "authorities": [
          {
            "authority": "ROLE_USER"
          }
        ],
        "details": {
          "sub": "f348bbbb-9441-4543-9940-9da31e50d877",
          "email _verified": true,
          "name": "Admin Administrator",
          "preferred_username": "admin",
          "given_name": "Admin",
          "family_name": "Administrator",
          "email": "admin@localhost"
        },
        "authenticated": true,
        "principal": "Admin Administrator",
        "credentials": "N/A",
        "name": "Admin Administrator"
      },
      "clientO nly": false,
      "principal": "Admin Administrator",
      "oauth2Request": {
        "clientId": "web_app",
        "scope": [

        ],
        "requestParameters": {

        },
        "resourceIds": [

        ],
        "authorities": [

        ],
        "approved": true,
        "refresh": false,
        "redirectUri": null,
        "responseTypes": [

        ],
        "extensions": {

        },
        "grantType": null,
        "refreshTok enRequest": null
      },
      "credentials": "",
      "name": "Admin Administrator"
    }

вот yo-rc.json:

{
    "generator-jhipster": {
        "promptValues": {
            "packageName": "xxxxxxxxxxx"
        },
        "jhipsterVersion": "5.7.2",
        "applicationType": "monolith",
        "baseName": "XXXXXXXXXX",
        "packageName": "xxxxxxxxxxxxxx",
        "packageFolder": "xxxxxxxxxxxxxx",
        "serverPort": "8080",
        "authenticationType": "oauth2",
        "cacheProvider": "ehcache",
        "enableHibernateCache": true,
        "websocket": false,
        "databaseType": "sql",
        "devDatabaseType": "h2Disk",
        "prodDatabaseType": "mysql",
        "searchEngine": false,
        "messageBroker": false,
        "serviceDiscoveryType": false,
        "buildTool": "maven",
        "enableSwaggerCodegen": false,
        "clientFramework": "angularX",
        "useSass": false,
        "clientPackageManager": "npm",
        "testFrameworks": [],
        "jhiPrefix": "jhi",
        "otherModules": [],
        "enableTranslation": false
    }
}

Как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 10 апреля 2019

В администрировании keycloak перейдите в раздел Клиенты >> YOUR_CLIENT >> Mappers -> Добавить новый mapper -> Установите для типа mapper значение «Роль клиента клиента», а для «Имя утверждения токена» - «полномочия», а для типа утверждения JSON - строку.

0 голосов
/ 22 марта 2019

У меня была та же проблема, я думаю, это связано с тем, что Keycloak дает роли клиента в другом утверждении "resource_access", а библиотека Spring Boot Security Oauth2 не считывает роли здесь.

Я изменил UserService.Java, чтобы сначала попытаться прочитать это утверждение и вспомогательное значение, соответствующее clientId, путем декодирования токена JWT, это чище, потому что он читает только роли клиента.

   public UserDTO getUserFromAuthentication(OAuth2Authentication authentication) {
    OAuth2AuthenticationDetails oauth2AuthenticationDetails = (OAuth2AuthenticationDetails) authentication
            .getDetails(); // should be an OAuth2AuthenticationDetails

    Map<String, Object> details = (Map<String, Object>) authentication.getUserAuthentication().getDetails();
    User user = getUser(details);
    String tokenValue = oauth2AuthenticationDetails.getTokenValue();
    DecodedJWT jwt = JWT.decode(tokenValue);

    Map<String, Object> resourceAccessClaim = jwt.getClaim("resource_access").asMap();
    String clientId = authentication.getOAuth2Request().getClientId();

    if (resourceAccessClaim.containsKey(clientId)) {
        ((Map<String, Object>) resourceAccessClaim.get(clientId)).values().forEach(rn -> {
            user.setAuthorities(extractAuthorities((List<String>) rn));
        });
    }
    if (user.getAuthorities() == null || user.getAuthorities().size() == 0) {
        user.setAuthorities(extractAuthorities(authentication, details));
    }

    // convert Authorities to GrantedAuthorities
    Set<GrantedAuthority> grantedAuthorities = user.getAuthorities().stream().map(Authority::getName)
            .map(SimpleGrantedAuthority::new).collect(Collectors.toSet());
...
...