2015-04-02 66 views
1

我建立,从网站上显示数据库中的信息的应用程序。该应用程序使用Spring Security进行保护,我的用户可以拥有不同的角色。记录应根据当前用户的角色显示。例如,我想显示来自数据库的书籍。角色X只能看到一些书籍和作用Y了。但角色ADMIN可以看到所有的书籍。如何授权Spring应用程序的服务层?

现在我不知道在哪里以及如何授权情况。我认为服务层将是一个很好的地方,但我怎样才能查询当前用户可以访问的角色。

我的表是这样的:

book (id, name) 
role (id, name) 
role_book (id, role_id, book_id) 

因此,对于图书的查询将SELECT b.id, b.name FROM book b, role r role_book rb WHERE b.id = rb.book_id AND r.id = rb.role_id AND r.name IN (<roles of the current user>)。当当前用户具有ADMIN角色时,我只需选择数据库中的所有书籍。

但是我怎么执行的春季服务方法这些查询?我认为这是一项常见的授权任务。有没有弹簧机制来做到这一点?

回答

2

我会做一个简单的重新设计,这也将使得数据层的可重用性。这将是这样的。

服务层

这里我们以当前用户的角色,并传递给数据层。

Iterable<Book> findAllMyBooks(){ 
... 
    List<String> roles = new ArrayList<>(); 
    Authentication authentication = SecurityContextHolder.getContext()getAuthentication(); 
    for (GrantedAuthority auth : authentication.getAuthorities()) { 
     roles.add(auth.getAuthority()); 
    } 
    bookRepository.findAllByRoles(roles); 
... 
} 

数据层

查询基于角色的书籍。因此,您可以使用它在管理面板中稍后为未登录的用户提取书籍。

请注意,我没有时间检查JPQL查询。 'ADMIN' IN (:roles)中可能有错误。请检查一下。

@Query("SELECT b FROM Book b INNER JOIN b.roles r WHERE r.name IN (:roles) OR 'ADMIN' IN (:roles)") 
Iterable<Book> findAllByRoles(@Param("roles") List<String> roles); 

实体模型

地图Many to manyRolesBooks

关系