Краткое описание: Я хочу, чтобы spring-data-rest генерировал только конечные точки, такие как "/ users / {userId} / settings", "/ users / {userId} / values", а не "/ settings" или "/ values" .
Подробнее:
Я начал раздражаться проверкой в каждой функции контроллера, имеет ли зарегистрированный пользователь доступ к запрошенному ресурсу и имел следующую идею для его автоматизации (если у кого-то есть идея получше, которая не вызывает проблем ниже, я был бы рад услышать)
В моем приложении пользователь имеет доступ только к своему ресурсу и не может видеть данные других пользователей.
Поэтому моя идея заключалась в том, чтобы ограничить (с помощью конфигурации Websecurity) все пути, начинающиеся с "/ users / {id} **", чтобы разрешить доступ только тогда, когда вошедший в систему пользователь имеет указанный идентификатор.
Таким образом, если мои конечные точки, например, "/ пользователей / {USERID} / userValues"
или "/ users / {userId} / settings" и т. д. каждый пользователь может получить доступ только к своим данным из-за правила разрешения
Для дальнейшей автоматизации процесса и обеспечения того, чтобы я не забывал проверку о userId в контроллере, я попытался использовать spring-data-rest, что прекрасно, за исключением одной проблемы:
spring-data-rest генерирует API-конечную точку для каждого объекта. Они выглядят так:
"/ settings", "/ users", "/ values".
Пути, которые я хочу, также генерируются: "/ users / {userId} / values" и "/ users / {userId} / values", и он корректно проверяет userId, поэтому моя идея, кажется, работает в принципе.
Однако я не могу понять, как отключить конечные точки, где путь начинается с дочернего элемента ("/ settings", "/ values".), Поскольку я хочу только конечные точки, начинающиеся с "/ users / {userId} "быть доступным.
Возможно ли это? Или есть лучший способ добиться того, чтобы пользователи могли видеть и редактировать только свои собственные данные?
Вот классы моего проекта для тестирования этого сценария (я знаю, что наименование ужасно, я настрою новый проект, если я знаю, что могу сделать эту работу, это только для тестирования):
Зависимости Gradle:
dependencies {
compile("org.springframework.boot:spring-boot-starter")
//web frontend
compile("org.springframework.boot:spring-boot-starter-web")
//rest endpoint generator
compile("org.springframework.boot:spring-boot-starter-data-rest")
//database connection
compile("mysql:mysql-connector-java")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
//Swagger (/v2/api-docs)
compile("io.springfox:springfox-swagger2:2.9.2")
//pretty swagger (/swagger-ui.html)
compile("io.springfox:springfox-swagger-ui:2.9.2")
//Lombok (automatic getter / setter)
compile("org.projectlombok:lombok:1.18.6")
}
Пользователь:
@Entity
@Getter
@Setter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String firstName;
private String lastName;
@OneToMany(mappedBy="user", cascade= CascadeType.ALL)
private List<UserValue> values;
@OneToOne
@RestResource(path = "settings", rel = "SettingsRel")
private Settings settings;
}
UserValue:
@Entity
public class UserValue {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Integer id;
String value;
@ManyToOne
@JoinColumn(name = "user_id")
@JsonIgnore
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Настройки:
@Entity
@Getter
@Setter
public class Settings {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Integer id;
private HashMap<String, Object> settings;
}
UserValueRepository:
public interface UserValueRepository extends CrudRepository<UserValue, Integer> {
}
UserRepository:
public interface UserRepository extends CrudRepository<User, Integer> {
}
SettingsRepository:
public interface SettingsRepository extends CrudRepository<Settings, Integer> {
}
Две дополнительные проблемы, с которыми я сталкиваюсь с spring-data-rest, заключаются в том, что он, похоже, не работает с Swagger и Lombok. Так что я еще более открыт для альтернативных способов достижения своей цели