2016-06-18 2 views
-2

Скажем, у меня есть таблица z проведение столбец a, b, c.Лучшая практика обеспечения весеннего mvc и спящего режима

Столбец a и b может использоваться любым авторизованным пользователем, а столбец c может использоваться только администраторами.

Мой объект спящего режима основан на таблице z. Мой контроллер весны mvc имеет метод чтения и записи. Я могу защитить контроллеры mvc, используя роли, используя весеннюю безопасность.

Проблема заключается в том, что мой клиент (угловой разговор через rest/json для контроллера) может получить доступ ко всем столбцам, установив значение для c (даже если клиентский интерфейс не предоставляет это явно) простой настройкой json объект и отправить его методу записи контроллеров. Кроме того, вызов метода чтения возвращает значение столбца c любому пользователю.

Какова хорошая практика доступа к этой таблице на основе ролей?

Хорошо, ниже конкретными видами Например:

Entity:

@Entity 
@Table(name = "hotel") 
@XmlRootElement 
public class Hotel extends BaseEntity implements Serializable { 

    private String name; 
    private String street; 
    private String houseNo; 
    private String postalcode; 
    private String city; 
    private String country; 
    private String shortDesc; 
    private Boolean landing; // admin acceess only 
} 

Backend Фасад:

@Component 
public class HotelAccessImpl extends BackendBaseAccess implements HotelAccess { 
    @Autowired 
    private AccountAccess accountAccess; 

    @Override 
    public List<Hotel> findAll() { 
     TypedQuery<Hotel> query = getEm().createQuery("FROM Hotel WHERE DELETED = false ORDER BY CREATED DESC", 
       Hotel.class); 
     List<Hotel> results = query.getResultList(); 
     return results; 
    } 

@Override 
@Transactional(value = "transactionManager", propagation = Propagation.REQUIRES_NEW) 
public Hotel upsert(Hotel hotel) { 
    if (find(hotel.getId()) == null) { 
     getEm().persist(hotel); 
    } else { 
     hotel = getEm().merge(hotel); 
    } 
    getEm().flush(); 
    return hotel; 
} 

} 

API (контроллер, где я ограничить доступ "только" на уровне метода)

@RestController 
@RequestMapping("hotel") 
public class HotelController extends BaseController { 
private static Logger logger = LogManager.getLogger(HotelController.class); 

@Autowired 
private FileAccess fileAccess; 
@Autowired 
private HotelAccess hotelAccess; 
@Autowired 
private MailAccess mailAccess; 


@RequestMapping(value = "list", method = RequestMethod.GET) 
public ResponseEntity<List<Hotel>> findAll() { 
    logger.info("FindAll"); 
    return new ResponseEntity<List<Hotel>>(hotelAccess.findAll(), HttpStatus.OK); 
} 

@RequestMapping(value = "upsert", method = RequestMethod.POST) 
public ResponseEntity<Hotel> upsert(@RequestBody Hotel hotel) { 
    logger.info("Upsert: " + hotel.getName()); 
    if (isAuthorized(hotel.getAccount())) { 
     Hotel response = hotelAccess.upsert(hotel); 
     if (response.isInitial()) { 
      mailAccess.sendHotelUpsert(response); 
     } 
     return new ResponseEntity<Hotel>(response, HttpStatus.OK); 
    } else { 
     return new ResponseEntity<>(HttpStatus.FORBIDDEN); 
    } 
} 
@Secured({ "ROLE_ADMIN" }) 
@RequestMapping(value = "delete", method = RequestMethod.POST) 
public ResponseEntity<Hotel> delete(@RequestBody Hotel hotel) { 
    logger.info("Delete: " + hotel.getId()); 
    boolean deleted = hotelAccess.delete(hotel); 
    return (deleted) ? new ResponseEntity<>(HttpStatus.OK) : new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); 
} 
+0

Необходимо уменьшить масштаб до более конкретной проблемы. См. [Ask] – charlietfl

+0

добавил код, надеюсь, теперь это даст больше объяснений. –

ответ

0

Вам необходимо подумать о том, чтобы обеспечить маршаллинг и разборку данных вашего объекта.

Других слов, для пользователей без прав администратора, вы хотите только полями Маршалловых A и B для клиента и маршализации полой A и B от клиента. Для пользователей-администраторов вы хотите сортировать и отменять все поля.

Вам необходимо предотвратить утечку защищенной информации клиенту на основе Javascript о поле C, когда пользовательский контекст не является администратором. Предотвращение вставки/обновления поля C для пользователей, не являющихся администраторами, недостаточно в зависимости от защищенного характера поля C.

+0

Есть ли способ сделать маршаллинг на основе роли во время выполнения? На данный момент маршаллинг выполняется джексоном на основе объекта, который имеет метод контроллера, - в моем случае всех членов сущности (включая членов администратора). –

+0

... и что происходит, когда член c не выделяется сущности (из-за правила безопасности) и объект записывается в базу данных? Будет ли спящий режим пропускать обновление столбца или перезапись столбца нулевым значением? –

0

не должен быть слишком трудно:

  1. С тем же или другим контроллером, создать отдельный API для чтения/записи, один набором для обычного пользователя, а другой набора для пользователей администратора.

  2. Использовать весеннюю безопасность, чтобы позволить Админам возможность доступа к API-интерфейсам администратора.

  3. Для обработки API, нормальный пользователь читает, нуль из любых элементов Z вы не хотите, чтобы обычный пользователь, чтобы увидеть перед отправкой вэлью:

    @RequestMapping(value = "/my/foo/{id}", method = RequestMethod.GET) 
        public Foo getFoo(@PathVariable String id, HttpServletResponse response) { 
         Foo foo = fooDao.getFoo(id); 
         if (foo != null) { 
          foo.setC(null); 
          return foo; 
         } else { 
          response.setStatus(HttpServletResponse.SC_NOT_FOUND); 
          return null; 
         } 
        } 
    
  4. Для записи, извлечения элемент из Hibernate на основе внутреннего идентификатора входящего объекта и обновить его только теми полями из входящего объекта, которые пользователь может обновить, а затем сохранить этот объект в базе данных.

+0

Этот способ кажется мне лишним. Я также решил сделать это, но я не уверен, что это хорошая практика. Совет по Наросу кажется лучшим способом сделать это. –

+0

Части из двух реализаций, которые оказываются избыточными, могут быть учтены в общем частном (не выходящем извне) методе, если это необходимо. Но мне кажется более безопасным обеспечить безопасность на основе URL-адреса API (например, строки 39-40 [здесь] (https://github.com/gmazza/tightblog/blob/b32c215e5c904070d02d6a837496819e05b953f4/app/src/main/webapp/WEB -INF/security.xml # L39)), поэтому метод даже не может быть введен, если только роли не выполняются, чем создать общий метод, который все пользователи могут вводить и полагаться на реализацию метода, чтобы гарантировать, что нормальные пользователи не выполняют что разрешено только админам. –

Смежные вопросы