使用Spring检查实体/对象是否属于当前登录的用户

时间:2014-03-17 12:36:43

标签: spring spring-mvc spring-security aspectj spring-data

我正在使用以下的Spring Web应用程序:

  • Spring MVC
  • Spring Core
  • Spring Roo
  • Spring Security
  • Spring Data JPA
  • Mysql的

我遇到的问题如下:每次访问从网络层到应用程序实体/对象我希望能检查他们是否确实属于当前用户

让我举例说明:应用程序的用户有广告,课程(称为实体/对象)。我经常使用PK / ID对这些对象/实体执行GET或POST,以便检索,更新或删除这些对象。截至目前,我还没有找到一种干净灵活的方法来阻止用户检索,更新或删除其他人的对象。

我使用Spring Security和我随时知道谁是当前用户(当前登录的用户/委托人)但我不确定在哪里(哪一层)以及如何执行检查

我曾尝试使用AspectJ建议服务和控制器方法,但我实现它的方式远非理想,因为仅仅方法签名的更改会导致建议不被应用。

我可以在Spring Security中使用ACL,但它增加了一个不必要的复杂层:我只需要授予或拒绝访问给定的实体,无论它们是否属于某个帐户/用户。

任何已经遇到此问题的人都可以提供干净,灵活和干燥的解决方案吗?

1 个答案:

答案 0 :(得分:5)

在我看来,这是授权问题。实际上,您希望确认当前用户具有对实体/对象执行操作的正确权限。因此,我建议您的解决方案应用于服务层(中间层)。

Spring Security架构的一个重要部分是处理授权决策。值得花时间阅读section of the documentation以确保您了解一般架构。

从广义上讲,Spring Security将预调用访问决策委托给AccessDecisionManagerAccessDecisionManager通常会查询已注册AccessionDecisionVoter的列表,正如其名称所暗示的那样,根据当前的执行状态,“是否”允许调用继续进行“投票”。谁登录,用户请求的数据。

AccessDecisionVoter如何决定是否提供访问权限完全取决于实施。因此,从理论上讲,您可以做任何事情来决定是否授权特定请求。

谢天谢地(正如您所料)Spring提供了一些相当明智的默认实现,可以让您实现开箱即用的功能。特别是我相信Method Security Expressions应该让你实现你想要的(它将取决于你的服务如何实现)。

根据文档,您可以使用Spring Security的@PreAuthorise注释以及一些查看当前方法调用或执行上下文的参数的表达式。例如:

@PreAuthorise("#u == principal.id")
public List<Foo> loadFoos(@P("u")String userId);

在此示例中,只有userId参数的值与当前经过身份验证的用户的id完全匹配时,才允许继续进行方法调用。

您的确切方法/表达方式取决于您的服务的实施方式,但希望这为您提供了一个良好的起点。

相关问题