SessionDestroyedEvent getSecurityContexts() 始终为空

Posted

技术标签:

【中文标题】SessionDestroyedEvent getSecurityContexts() 始终为空【英文标题】:SessionDestroyedEvent getSecurityContexts() always empty 【发布时间】:2012-06-26 15:11:28 【问题描述】:

我有一个使用 Spring 3.1.1 和 Spring Security 3.1.0 的 Web 应用程序。我实现了一个 ApplicationListener,它检查 SessionDestroyedEvent(s) 并记录用户名和其他数据。但是,getSecurityContexts() 总是返回一个空集合。我正在针对 LDAP 服务器进行身份验证。我还检查了 getSource() 方法,它返回包含 Principal 信息的会话数据。但是,这些对象是不同的容器特定实现,并且没有我可以使用的接口/抽象类。我的问题是这是否是 SpringSecurity 中的一个错误,还是我可以做一些额外的配置?

以下是一些相关代码:

@Service
public class ApplicationSecurityListener implements ApplicationListener<ApplicationEvent>

@Override
  public void onApplicationEvent(ApplicationEvent event)
  
           else if ( event instanceof SessionDestroyedEvent )
    
        SessionDestroyedEvent sessinEvent = ( SessionDestroyedEvent ) event;
        //System.out.println ( "SessionDestroyedEvent:" + sessinEvent.getId() );
        //load session if it is not empty
        if(sessinEvent.getSecurityContexts() != null && !sessinEvent.getSecurityContexts().isEmpty())
        
            ...
            

【问题讨论】:

【参考方案1】:

这是 3.1.0 中的一个错误,将作为 3.1.1 的一部分发布(请参阅SEC-1870)。在 3.1.1 发布之前,您可以通过手动获取 onApplicationEvent 中的 SecurityContext 来解决此问题。使用前面提到的 JIRA 中的 changeset 作为指南,您会想出如下内容:

public void onApplicationEvent(ApplicationEvent event) 
    if(event instanceof SessionDestroyedEvent) 
        SessionDestroyedEvent sdEvent = (SessionDestroyedEvent) event;    
        HttpSession session = sdEvent.getSession();    
        Enumeration<String> attributes = session.getAttributeNames();    
        ArrayList<SecurityContext> contexts = new ArrayList<SecurityContext>();

        while(attributes.hasMoreElements()) 
            String attributeName = attributes.nextElement();
            Object attributeValue = session.getAttribute(attributeName);
            if (attributeValue instanceof SecurityContext) 
                contexts.add((SecurityContext) attributeValue);
            
        
        /* ... do things with the contexts (may be empty) ...*/
    

    /* ... handle other conditions ... */


如果您知道只有一个 SecurityContext 并且您没有更改存储 SecurityContext 的属性名称(典型),您也可以使用以下方法获取它:

public void onApplicationEvent(ApplicationEvent event) 
    if(event instanceof SessionDestroyedEvent) 
        SessionDestroyedEvent sdEvent = (SessionDestroyedEvent) event;    
        HttpSession session = sdEvent.getSession();
        String attrName = HttpSessionSecurityContextRepository
            .SPRING_SECURITY_CONTEXT_KEY;
        SecurityContext context = session.getAttribute(attrName);

        /* ... do things with the context (may be null) ...*/
    

    /* ... handle other conditions ... */


【讨论】:

以上是关于SessionDestroyedEvent getSecurityContexts() 始终为空的主要内容,如果未能解决你的问题,请参考以下文章

Ember.get() 和 this.get() 的区别

使用 set; get; 而不是 get;放;

C语言中如何用 gets(),put()

node 怎么获取get的参数

get请求

访问PHP发送多个get请求