2009-07-23 27 views
1

をゼロに私がSecurityContextがを返すためのSpring Beanを設定している:私はこのBeanを使用する場合春のセキュリティは、次のように認証リターンが

<bean id="securityContext" class="org.springframework.security.context.SecurityContextHolder" 
    factory-method="getContext"> 
</bean> 

認証オブジェクトがnullを返します。

Authentication authentication = securityContext.getAuthentication(); 
GrantedAuthority[] authorities = authentication.getAuthorities(); 

上記の2行目はNPEを引き起こします。これは期待通りに次のコードは、当局に返すよう、私には奇妙に思える:

GrantedAuthority[] authorities = 
SecurityContextHolder.getContext().getAuthentication().getAuthorities(); 

は基本的に私は私のコードをよりテスト可能にするために)Sec​​urityContextHolder.getContext(への静的呼び出しを排除しようとしています。

これを解決する方法についてのご意見はありますか? Springで返されたSecurityContextが、自分のコード内からの静的呼び出しが行える間に権限を返すことができないのはなぜですか?

FYI私はStruts 2アクション内からコードを実行しています。

答えて

2

SecurityContextHolder.getContext()は、現在のスレッドに関連付けられているコンテキストを返します。 Beanのインスタンス化では、Beanに格納されるコンテキストは、アプリケーションの実行時に必要なコンテキストとは異なります。私は、Beanにコンテキストを格納し、これを常に使用することは可能ではないと思います。

+1

私はこれに同意し、フレームワークと戦わないでください。 – JamesC

+2

それは良い問題の説明ですが、解決策ではありません。 – msangel

0

静的アプローチを使用してコードをテスト可能にすることができます。あなたは、単に「userDetails」上記の例では

//Assuming you've loaded the user, create your stub 
Authentication authentication = new TestAuthentication(userDetails); 
//Update the context 
SecurityContextHolder.getContext().setAuthentication(authentication); 
...あなたのJUnitテストでそうorg.springframework.security.Authentication

の独自の実装を作成する必要がある「のUserDetailsを実装するクラスです通常、ドメインUserオブジェクトをラップします。

マイTestAuthenticationクラスは - これは、それは基本的にシングルトンであるので、あなたが作成したBeanがscope-を定義していないので、それが起こる

public class TestAuthentication implements Authentication { 

    private UserDetails userDetails; 
    private boolean authentication = true; 

    public TestAuthentication(UserDetails userDetails){ 
     NullArgumentException.assertNotNull(userDetails, "userDetails"); 
     this.userDetails = userDetails; 
    } 

    public TestAuthentication(UserDetails userDetails, boolean authentication){ 
     NullArgumentException.assertNotNull(userDetails, "userDetails"); 
     this.userDetails = userDetails; 
     this.authentication = authentication; 
    } 


    public GrantedAuthority[] getAuthorities() { 
     return userDetails.getAuthorities(); 
    } 


    public Object getCredentials() { 
     return null; 
    } 


    public Object getDetails() { 
     return null; 
    } 


    public Object getPrincipal() { 
     return this.userDetails; 
    } 


    public boolean isAuthenticated() { 
     return authentication; 
    } 


    public void setAuthenticated(boolean arg0) 
      throws IllegalArgumentException { 
     this.authentication = arg0; 
    } 


    public String getName() { 
     return null; 
    } 
} 
+0

提案していただきありがとうございます。このような方法ではなく、認証とGrantedAuthorityのものを含むテストダミーとスタブの束を作成する必要があります。しかし、最終的にこれは私が取らなければならなかったアプローチです。 :-) –

+0

虚偽のUserDetailsオブジェクトを簡単に使用して、setAuthenticationにそのオブジェクトを渡すことができます。認証の認証= EasyMock.createNiceMock(Authentication.class); EasyMock.expect(authentication.getPrincipal()).Return(userDetails); SecurityContextHolder.getContext()。setAuthentication(認証); –

0

に役立ちます願っています。 希望どおりに動作させるには、リクエスト/セッションスコープにする必要があります。

関連する問題