Клиент разрешил идентификаторы ресурсов, потерянные, когда отдельные серверы авторизации и ресурсов - PullRequest
0 голосов
/ 22 января 2019

У меня есть сервер авторизации и сервер ресурсов (отдельное приложение). Пока я не хочу использовать токены JWT. Сервер авторизации предоставляет конечную точку / user / me для получения аутентификации вызывающей стороны:

    @GetMapping("/user/me")
    public Principal me(final Principal principal) {
        return principal;
    }

Сервер ресурсов вызывает эту конечную точку, предоставляя в заголовке HTTP токен доступа. Таким образом, при наличии токена доступа сервер ресурсов извлекает аутентификацию, которая создала этот токен. Когда HTTP-запрос, исходящий от сервера ресурсов, попадает в эту конечную точку (он настраивается со свойством security.oauth2.resource.user-info-uri ), он проходит через OAuth2AuthenticationProcessingFilter . Этот фильтр извлекает токен доступа из заголовка благодаря TokenExtractor , и полученная (предварительная) аутентификация пытается аутентифицироваться с помощью OAuth2AuthenticationManager :

  Authentication authResult = authenticationManager.authenticate(authentication);

Поскольку мой сервер ресурсов и мой сервер авторизации являются двумя разными серверами, диспетчер аутентификации представляет собой UserInfoTokenServices .

  OAuth2Authentication auth = tokenServices.loadAuthentication(token);

UserInfoTokenServices выполняет вызов REST для конечной точки / user / me сервера авторизации и отображает извлеченное содержимое во вновь созданную OAuth2Authentication , которая возвращается вернуться к authenticate () .

Моя проблема в том, что это отображение, похоже, неверно. Ответ REST, возвращаемый / user / me , имеет полномочия и данные пользователя, флаг, указывающий, что они аутентифицированы, раздел для аутентификации пользователя ( userAuthentication ), раздел для аутентификация клиента ( oauth2Request ), а также пара других записей. Сопоставление, выполненное с помощью UserInfoTokenServices.extractAuthentication () , создает новый OAuth2Authentication , имеющий пустой сохраненный запрос (часть, которая представляет собой аутентификацию клиента). Информация клиента, такая как области и идентификаторы ресурсов, теряется. И действительно, обратно в authenticate () следующий тест пропускается:

    Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds();
    if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) {
        throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")");
    }

потому что resourceIds пусто, потому что, как уже говорилось, auth - это новая OAuth2Authentication , которая потеряла клиентскую часть аутентификации. Это означает, что клиент, зарегистрированный на моем сервере авторизации с определенными ресурсами, может фактически получить доступ к любому ресурсу. Например. клиент

  clientDetailsServiceConfigurer
                .inMemory()
                .withClient("client")
                ...
                .resourceIds("foo")
                ...

может получить доступ к ресурсу с bar id.

Почему UserInfoTokenServices.extractAuthentication () делает это и как я могу решить мою проблему?

Чтобы быть абсолютно точным, информация не полностью теряется UserInfoTokenServices.extractAuthentication () , поскольку ответ на вызов REST на / user / me сохраняется в части сведений новой OAuth2Authentication :

    token.setDetails(map);

но это бесполезно, так как код здесь не ищет идентификаторы ресурсов. Для информации я использую код типа предоставления.

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