使用Spring Security Core PlugIn登录Grails应用程序上下文之外的用户信息

时间:2014-10-11 09:17:06

标签: java spring spring-mvc grails spring-security

我正在使用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'。

有人告诉我,如何在我想要的目录中访问这些信息? 谢谢你的时间

2 个答案:

答案 0 :(得分:2)

实际上,Spring Security使用HttpSession来存储SecurityContext,因此您可以在任何可以访问HttpSessionHttpServletRequest的地方访问它:

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对象作为入口点传递。

对于src / groovy和src / java中的代码:

假设您在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

中注册您的bean
// 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

    }
}

同样的概念适用于服务。只需记住将从控制器获取的请求对象作为参数传递给服务。