Один @PreAuthorize ("hasAuthority ('ACCOUNT OWNER')") работает, другой очень похожий - выбрасывает SpelEvaluationException - PullRequest
1 голос
/ 22 октября 2019

У меня проблема с Spring Security и GraphQL.

У меня есть два похожих класса:

UserProfileQuery:

@Component
@AllArgsConstructor
class UserProfileQuery implements GraphQLQueryResolver {

    private final UserProfileRepository userProfileRepository;
    private final AddressRepository addressRepository;

    @PreAuthorize("hasAuthority('ACCOUNT_OWNER')")
    public List<UserProfile> getUserProfiles() {
        return userProfileRepository.findAll();
    }

    @PreAuthorize("hasAuthority('ACCOUNT_OWNER')")
    public Optional<UserProfile> getUserProfile(Long id) { return userProfileRepository.findById(id); }

    @PreAuthorize("hasAuthority('ACCOUNT_OWNER', 'USER')")
    public Set<Address> getAddresses(Long id) {
        return Optional.of(addressRepository.findByUserId(id)).orElseThrow(() -> new NotFoundException(UserProfile.class));
    }

}

и AddressQuery:

@Component
@AllArgsConstructor
class AddressQuery implements GraphQLQueryResolver {

    private final AddressRepository addressRepository;

    @PreAuthorize("hasAuthority('ACCOUNT_OWNER')")
    public List<Address> getAddresses() {
        return addressRepository.findAll();
    }

    @PreAuthorize("hasAnyAuthority('ACCOUNT_OWNER', 'USER')")
    public Address getAddress(Long id) {
        return addressRepository.findById(id).orElseThrow(() -> new NotFoundException(Address.class));
    }

}

Обе сущности, UserProfile и Address, имеют свои собственные graphqls файлы. Короче говоря, я просто опубликую важные фрагменты этих файлов:

userprofile.graphqls:

extend type Query {
    userProfiles: [UserProfile]
    addresses(id: ID): [Address]
    userProfile(id: ID): UserProfile
}

и address.graphqls:

extend type Query {
    addresses: [Address]
    address(id: ID): Address
}

Теперь,когда я запрашиваю UserProfiles:

query {
  userProfiles {
      id
        fullName
    }
  }

я получаю обычный ответ (просто пример данных, не обращайте на это внимания):

{
  "data": {
    "userProfiles": [
      {
        "id": "1",
        "fullName": "adgadgd"
      },
      {
        "id": "2",
        "fullName": "adgadgd"
      }
    ]
  }
}

, но делаю аналогичный запрос по адресам:

query {
  addresses {
      id
        city
    }
  }

Я получаю:

{
  "data": {
    "addresses": null
  },
  "errors": [
    {
      "extensions": null,
      "message": null,
      "locations": [],
      "errorType": "DataFetchingException",
      "path": null
    }
  ]
}

и в консоли получаю ошибку:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method hasAuthority(java.lang.String,java.lang.String) cannot be found on type org.springframework.security.access.expression.method.MethodSecurityExpressionRoot

Чего мне не хватает? Оба запроса похожи, и работает только один ...

1 Ответ

0 голосов
/ 22 октября 2019

Наконец, кажется, что GraphQL не любит одинаковые имена в методах Query / Mutation. В AddressQuery я изменил имя метода с

public List<Address> getAddresses()

на

public List<Address> getAllAddresses() {

и распространил это изменение на address.graphqls:

extend type Query {
    allAddresses: [Address]
    address(id: ID): Address
}

Теперь запросчтобы получить все адреса в AddressQuery работает как шарм.

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