我正在使用Spring Security Core PlugIn处理Grails应用程序。我想在grails应用程序上下文/控制器范围之外使用Spring Security Core访问当前登录的用户信息。任何人都可以告诉我,我们怎样才能获得有关控制器外部当前登录用户信息的信息。我想在grails应用程序的resources / services目录中访问此信息。
我尝试使用:SecurityContextHolder.getContext()。getAuthentication()。principal.username; 但我使用 grails.anonymous.user
进行匿名身份验证我使用httpSession尝试了另一种方法:
HttpSession session = RequestContextHolder.currentRequestAttributes().getSession()
session.properties.each {
println it;
}
SpringSecurityUtils.getSecurityContext(session).authentication.principal
但通过这种方式我也无法获得当前登录用户信息。因为httpSession对象不包含属性' SPRING_SECURITY_CONTEXT_KEY'。
有人告诉我,如何在我想要的目录中访问这些信息? 谢谢你的时间
答案 0 :(得分:2)
实际上,Spring Security使用HttpSession
来存储SecurityContext
,因此您可以在任何可以访问HttpSession
或HttpServletRequest
的地方访问它:
SecurityContext securityContext = (SecurityContext)httpSession.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
def username = securityContext.getAuthentication().principal.username
默认情况下, SecurityContextHolder
使用ThreadLocal
变量来存储上下文,因此如果要从另一个线程检索信息,它将无法获取任何信息并将创建空上下文。这是您获得匿名身份验证的可能原因之一。
答案 1 :(得分:0)
我认为jasp解释了一下。您可以从外部grails访问getAuthentication()。principal.username,前提是您将从控制器或过滤器获取的javax.servlet.http.HttpServletRequest对象作为入口点传递。
假设您在ExampleClazz.groovy
src/groovy
的班级
package com.test
import org.springframework.security.web.context.HttpSessionSecurityContextRepository
class ExampleClazz {
def receiveRequest(javax.servlet.http.HttpServletRequest request){
def userDetails = request.getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY)
if(userDetails){
println userDetails.getAuthentication().principal.username
return userDetails.getAuthentication().principal.username
}else{
return null
}
}
}
要调用此自定义类,请在resource.groovy
// Place your Spring DSL code here
import com.test.ExampleClazz
beans = {
sampleBean(ExampleClazz)
}
要调用ExampleClazz,您可以将其注入控制器或过滤器。 在过滤器中:
class ExampleFilters {
def sampleBean
def filters = {
// your filters here
someURIs(controller:'securepage',action:'index') {
before = {
println "before request"
println sampleBean.receiveRequest(request) //<--the HttpServletRequest
}
}
}
}
在控制器中:
package com.test
class SomeController {
def sampleBean
def index() {
sampleBean.receiveRequest(request)//<--the HttpServletRequest
}
}
同样的概念适用于服务。只需记住将从控制器获取的请求对象作为参数传递给服务。