5

我是Grails的新手。我正在使用Spring Security Grails 插件进行身份验证。我想在我的视图 gsp 文件中获取当前用户。

我正在尝试这样...

<g:if test="${post.author == Person.get(springSecurityService.principal.id).id }">
      <g:link controller="post" action="edit" id="${post.id}">
            Edit this post
      </g:link>
</g:if>

在这里,我想仅显示由已登录用户创建的那些帖子的编辑此帖子链接。但它显示错误 -

Error 500: Internal Server Error

 URI
    /groovypublish/post/list
 Class
   java.lang.NullPointerException
 Message
   Cannot get property 'principal' on null object

这是我的 Post.groovy——

class Post {

static hasMany = [comments:Comment]

String title
String teaser
String content
Date lastUpdated
Boolean published = false
SortedSet comments
Person author

....... more code ....

这是我的 Person.groovy 域类文件——

class Person {

transient springSecurityService

String realName
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
byte[] avatar
String avatarType

static hasMany = [followed:Person, posts:Post]
static searchable = [only: 'realName']
    ........ more code ......

请帮忙。

4

4 回答 4

15

您可以使用Spring Security Taglibs。对于您想要做的事情,检查登录用户是否是帖子的所有者,您可以执行以下操作:

<sec:isLoggedIn>
<g:if test="${post.author.id == sec.loggedInUserInfo(field: 'id')}">
      <g:link controller="post" action="edit" id="${post.id}">
            Edit this post
      </g:link>
</g:if>
</sec:isLoggedIn>

如果你发现你需要做这个检查很多,我建议把它放到一个自定义标签库中

class AuthTagLib {

  def springSecurityService

  def isOwner = { attrs, body ->
    def loggedInUser = springSecurityService.currentUser
    def owner = attrs?.owner

    if(loggedInUser?.id == owner?.id) {
      out << body()
    }
  }
}

然后像这样使用它

<g:isOwner owner="${post?.author}">
  <g:link controller="post" action="edit" id="${post.id}">
    Edit this post
  </g:link>
</g:isOwner>
于 2013-07-08T12:34:43.033 回答
7

尝试 springSecurity 插件提供的标签,例如:

<sec:isLoggedIn>

  <g:link controller="post" action="edit" id="${post.id}">
            Edit this post
      </g:link>

</sec:isLoggedIn>

实际上你正试图在你的 GSP 页面上注入服务,你可以在页面上使用一些 import 语句来做到这一点,但我会说这不是一个好的编程习惯,我认为你应该从控制器发送当前登录用户的实例到 GSP 页面,然后对其进行检查:

假设你有控制器方法:

def showPostPage(){
Person currentLoggedInUser = springSecurityService.getCurrentUser();
[currentLoggedInUser:currentLoggedInUser]
}

在您的 GSP 页面上:

<g:if test="${post.author == currentLoggedInUser }">
      <g:link controller="post" action="edit" id="${post.id}">
            Edit this post
      </g:link>
</g:if>
于 2013-07-08T12:31:33.443 回答
0

看起来现有的标签,它们是 Spring Security 插件的一部分,对你来说还不够,对吗?查看文档

我的建议是向 Person 实体添加一个新方法,它以 Post 作为参数并返回 true/false,如果它可以编辑(反之亦然,向 Post 实体添加新方法,它以 Person 作为参数,这个由您决定)。

然后,您可以创建自己的标签,利用此方法使您的 GPS 更好,即使这不是强制性步骤。

于 2013-07-08T12:34:33.593 回答
0

另一种方法是创建一个过滤器并将用户作为过滤器的一部分放在请求范围内,如下所示:

class SetCurrentUserFilters {
    def springSecurityService
    def filters = {
        all(controller: '*', action: '*') {
            before = {
                if (springSecurityService.isLoggedIn()){
                    request.setAttribute("current_user", springSecurityService.currentUser);
                }
            }
            after = { Map model ->

            }
            afterView = { Exception e ->

            }
        }
    }
}

然后您的 GSP 只需要查找“current_user”属性,如下所示:

<g:if test="${current_user.property}"> ... </g:if>
于 2015-10-21T18:12:39.923 回答