简体   繁体   English

使用Spring Security Core插件在Grails应用程序上下文之外获取登录用户信息

[英]Getting LoggedIn User Info Outside Grails Application Context with Spring Security Core PlugIn

I am working on Grails Application with Spring Security Core PlugIn. 我正在使用Spring Security Core插件开发Grails应用程序。 I want to access the currently loggedIn user info with Spring Security Core outside the grails application context/controller scope. 我想使用Grails应用程序上下文/控制器范围之外的Spring Security Core访问当前登录的用户信息。 Can anyone please tell me that how can we get the information regarding currently loggedIn user info outside controller. 任何人都可以告诉我,我们如何在控制器外部获取有关当前登录用户信息的信息。 I want to access this information in resources/services directory of grails application. 我想在grails应用程序的resources / services目录中访问此信息。

I tried this using: SecurityContextHolder.getContext().getAuthentication().principal.username; 我尝试使用:SecurityContextHolder.getContext()。getAuthentication()。principal.username; But I get Anonymous authentication with grails.anonymous.user 但是我通过grails.anonymous.user获得了匿名身份验证

I tried another way too for this using httpSession: 我也使用httpSession尝试了另一种方法:

 HttpSession session = RequestContextHolder.currentRequestAttributes().getSession()

 session.properties.each {
      println it;
 }

 SpringSecurityUtils.getSecurityContext(session).authentication.principal

But by this way too I couldn't get the Currently LoggedIn User Info. 但是通过这种方式我也无法获得当前登录用户信息。 Because httpSession object didn't contain attribute 'SPRING_SECURITY_CONTEXT_KEY'. 因为httpSession对象不包含属性“ SPRING_SECURITY_CONTEXT_KEY”。

Anybody tell me that how may I access this information in my desired directories ? 有人告诉我如何在所需目录中访问此信息? Thanks for your time 谢谢你的时间

Actually Spring Security uses HttpSession to store SecurityContext , so you can access it everywhere you can access HttpSession or HttpServletRequest : 实际上,Spring Security使用HttpSession来存储SecurityContext ,因此您可以在可以访问HttpSessionHttpServletRequest任何地方访问它:

SecurityContext securityContext = (SecurityContext)httpSession.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
def username = securityContext.getAuthentication().principal.username

SecurityContextHolder by default uses ThreadLocal variable to store context, so if you are retrieving information from another thread, it couldn't get any information and will create empty context. 默认情况下, SecurityContextHolder使用ThreadLocal变量存储上下文,因此,如果您要从另一个线程检索信息,它将无法获取任何信息,并将创建空上下文。 That's one of the possible reasons you've got anonymous authentication. 这就是您获得匿名身份验证的可能原因之一。

I think jasp explained a little bit. 我认为jasp解释了一下。 You can access the getAuthentication().principal.username from outside grails provided that you pass the javax.servlet.http.HttpServletRequest object that you obtained from controllers or filters as entry point. 如果您传递从控制器或过滤器获得的javax.servlet.http.HttpServletRequest对象作为入口点,则可以从外部grails访问getAuthentication()。principal.username。

For code in src/groovy and src/java: 对于src / groovy和src / java中的代码:

Say you have a class named ExampleClazz.groovy in src/groovy 假设您在src/groovy有一个名为ExampleClazz.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
        }
    }

}  

To call this custom class, you register your bean in resource.groovy 要调用此定制类,请在resource.groovy注册您的bean。

// Place your Spring DSL code here
import com.test.ExampleClazz
beans = {
    sampleBean(ExampleClazz)
}

To call the ExampleClazz, you can inject it either in controller or filter. 要调用ExampleClazz,可以将其注入控制器或过滤器中。 In Filter: 在过滤器中:

class ExampleFilters {
   def sampleBean
   def filters = {
        // your filters here

        someURIs(controller:'securepage',action:'index') {
            before = {
                println "before request"
                println sampleBean.receiveRequest(request) //<--the HttpServletRequest
            }
        }
   }
}

In Controller: 在控制器中:

package com.test

class SomeController {
    def sampleBean
    def index() { 
        sampleBean.receiveRequest(request)//<--the HttpServletRequest

    }
}

The same concept goes for services. 相同的概念适用于服务。 Just remember to pass the request object obtained from controllers as parameters in services. 只需记住将从控制器获取的请求对象作为服务中的参数传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM