1

Spring3.1.1とSpringSecurity3.1.0を使用するWebアプリがあります。SessionDestroyedEvent(s)をチェックし、ユーザー名とその他のデータをログに記録する必要があるApplicationListenerを実装しました。ただし、getSecurityContexts()は常に空のコレクションを返します。LDAPサーバーに対して認証しています。getSource()メソッドもチェックしましたが、プリンシパル情報を保持するセッションデータが返されます。ただし、オブジェクトはコンテナ固有の実装であり、異なるため、使用できるインターフェイス/抽象クラスはありません。私の質問は、これが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())
        {
            ...
            }}}}
4

1 に答える 1

2

これは3.1.1のバグであり、3.1.1の一部としてリリースされます(SEC-1870を参照)。3.1.1がリリースされるまでは、onApplicationEventのSecurityContextを手動で取得することで問題を回避できます。前述のJIRAのチェンジセットをガイドとして使用すると、次のようなものが思い浮かびます。

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が1つしかないことがわかっていて、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 ... */

}
于 2012-06-27T02:27:38.410 に答える