我是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>
在这里,我想显示编辑此帖子链接,仅指向由signed_in用户创建的帖子。但它显示错误-
Error 500: Internal Server Error
URI
/groovypublish/post/list
Class
java.lang.NullPointerException
Message
Cannot get property 'principal' on null object
这是我的帖子。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 ......
请帮忙。
您可以使用Spring Security Taglib。对于您想做的事情,检查登录用户是否是帖子的所有者,您可以做以下操作:
<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>
试试springSecurity插件提供的标签,比如:
<sec:isLoggedIn>
<g:link controller="post" action="edit" id="${post.id}">
Edit this post
</g:link>
</sec:isLoggedIn>
事实上,你正试图在你的GSP页面上注入一项服务,你可以在页面上使用一些导入语句来完成,但我认为这不是一个好的编程实践,我认为你应该将当前登录用户的实例从控制器发送到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>
另一种方法是创建一个过滤器,并将用户作为过滤器的一部分放入请求范围,如下所示:
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>
作为Spring Security插件的一部分,现有的标签似乎对您来说不够,对吗?参见文件
我的建议是向Person实体添加一个新方法,该实体将Post作为参数,如果可以编辑,则返回true/false(反之亦然,向Post实体添加新方法,将Person作为参数,这取决于您的决定)。
然后,你可以创建自己的标签,利用这种方法,使你的GPS更好,即使这不是强制性的步骤。