2

我正在尝试制作一个简单的论坛,只是为了掌握 Spring Security 和 MVC 框架的窍门。

为简单起见,让我们有一个 JSP 来查看论坛帖子,如下所示:

<body>
    ...

    Title: ${forumPost.title} <br>
    Author: ${forumPost.author.name} <br>
    Message: {forumPost.message} <br>

    <security:authorize ifAnyGranted="ROLE_ADMIN">
        Edit: <a href="/edit">Edit</a>
    </security:authorize>

    ...
</body>

我的问题是:管理员不仅应该能够编辑这篇文章,而且原作者也应该能够。因此,我只希望ROLE_ADMIN 和原作者能够看到Edit 链接。但是我不确定如何使用security:authorize标签按用户过滤,或者我是否需要以不同的方式进行此操作。

任何建议将不胜感激。谢谢!

4

4 回答 4

3

假设您有一个位于此页面后面的控制器,我将简单地添加一个类似于(半伪代码)的canEditPost字段:ModelAndView

private boolean isAdmin() {
    Authentication currentAuthObj = SecurityContextHolder.getContext().getAuthentication();
    List<GrantedAuthority> authorities = Arrays.asList(currentAuthObj.getAuthorites());
    for (GrantedAuthority auth : authorities) {
        if ("ROLE_ADMIN".equals(auth.getAuthority())) {
            return true;
        }
    }
    return false;
}

boolean currentUserIsAuthor = ...;

modelAndView.addObject("canEditPost", 
    Boolean.valueOf(currentUserIsAuthor || isAdmin());

然后在您看来,只需引用 $canEditPost。

通常,视图只引用模型中的一个简单标志比让视图/模板执行实际逻辑要好。

于 2009-06-01T17:43:10.620 回答
0

您的Author对象是否equals以每个作者都是独一无二的方式实现?

如果是这样,您可以简单地检查是否Author与当前用户相同(您将有两组标签)。

于 2009-06-01T17:14:34.760 回答
0

@matt b 的回答是一个很好的方法,可能是我最终会做的。但我发现了另一种更复杂的方法,但可以实现我在这篇文章中提出的内容。

我做了一些阅读,发现您可以在域对象级别处理安全性,并且本质上为角色或任意对象(例如当前用户 ID)赋予读/写/删除权限。在此示例中,我将授予当前用户 id 访问域对象的权限,在本例中是一个 ForumPost 对象,该对象在数据库中具有自己的唯一 id。

然后,当前用户 ID 将被授予读写访问权限,这可以(通过 XML 配置)定义为各种自定义角色(我相信正确的术语实际上是 Voter)。然后我可以命名这个选民MESSAGE__EDIT

因此,在我的 JSP 中,我可以使用以下内容:

安全性:授权 ifAnyGranted="MESSAGE_EDIT"

它会(再次通过 XML 配置)获取当前用户 ID 并根据当前域对象(在本例中为 ForumPost 对象)授予访问权限。

这比听起来要多得多,但绝对可以完成。

在 Spring Security Reference Documentation ( http://static.springframework.org/spring-security/site/reference/html/springsecurity.html ( 出于某种原因链接域对象安全部分现在已损坏))。

于 2009-06-01T18:15:14.780 回答
0

你可以有条件

<% if(mycondition.isTrue()){ %>
<security:authorize ifAnyGranted="ROLE_ADMIN">
    Edit: <a href="/edit">Edit</a>
</security:author
<% }%>
于 2009-06-01T18:18:55.897 回答