SessionDestroyedEvent getSecurityContexts()始终为空

时间:2012-06-25 11:00:24

标签: events session spring-mvc spring-security logout

我有一个使用Spring 3.1.1和Spring Security 3.1.0的Web应用程序。我实现了一个ApplicationListener来检查SessionDestroyedEvent,并且应该记录用户名和其他数据。但是,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 个答案:

答案 0 :(得分:2)

这是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 ... */

}