Как реализовать доступ, защищенный именем пользователя весной - PullRequest
0 голосов
/ 20 июня 2019

У меня есть случай, когда определенные конечные точки на контроллере должны возвращать 401, если имя пользователя, с которым аутентифицировался пользователь, совпадает с именем пользователя, с которым он работает.

Я думал о лучшем способе сделать это. В настоящее время у меня есть фасад аутентификации (https://www.baeldung.com/get-user-in-spring-security), где я проверяю в теле каждого метода контроллера, должен ли пользователь иметь доступ для работы с элементом, который он запрашивает.

IE. Пользователь должен иметь возможность удалить только свою учетную запись:

User u = service.findOne(id);
if (u != null) {
    // user can only delete their own account
    User authenticated = authenticationFacade.getAuthUser();
    RestPreconditions.checkRequestState(authenticated.getId() == u.getId());
}

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

IE

Post p = service.findOne(id);
if (p != null) {
        // user can only delete their own posts
        User authenticated = authenticationFacade.getAuthUser();
        RestPreconditions.checkRequestState(authenticated.getId() == p.getUser().getId());
}

Я здесь, чтобы спросить, является ли это лучшим способом. Как показано выше, некоторые проверки требуют работы с различными объектами и выполнения вызовов базы данных, чтобы получить данные, чтобы определить, должен ли пользователь иметь доступ.

Я рассматривал реализацию на основе ролей и задавался вопросом, может ли кто-нибудь дать некоторое представление о том, как я это сделаю, и будет ли он чище, чем описанный выше метод.

Причина, по которой я спрашиваю, заключается в том, что я также хочу, чтобы люди с ролью ROLE_ADMIN могли выполнять все операции, но мне нужно преобразовать текущие проверки в или || с текущими проверками, и это кажется грязным. Но просто предварительно авторизовать только роль администратора все равно не получится с фасадом без или

1 Ответ

1 голос
/ 20 июня 2019

Проверьте около @PreAuthorize / @PostAuthorize, что позволяет использовать SpEL для защиты вызова метода декларативным способом.

Одна из самых приятных вещей в том, что вы даже можете использовать SpEL для ссылки на метод пружинного боба , что означает, что вы можете сделать что-то вроде ниже.

Во-первых, определение bean-компонента для инкапсуляции всех проверок, связанных с безопасностью. Предположим, что все сущности реализуют некоторый интерфейс (например, BaseEntity), который может получить владельца этой сущности:

@Service
public class SecurityService{

     public boolean isAllowAccessedByCurrentUser(BaseEntity entity) {
            User authenticated = authenticationFacade.getAuthUser();
            return authenticated.getId() == entity.getOwnerId();
     }
}

Чтобы использовать его для проверки безопасности:

@Service
public class UserService {

    //"returnObject" is the built-in variable referring to the return object 
    @PostAuthorize ("@securityService.isAllowAccessedByCurrentUser(returnObject)")
    public User findOne(Integer id){

    }
}



@Service
public class PostService {

    //"returnObject" is the built-in variable refer to the return object of the method
    @PostAuthorize ("@securityService.isAllowAccessedByCurrentUser(returnObject)")
    public Post findOne(Integer id){

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