2009-05-21 15 views
19

私は春のセキュリティフレームワークを使用しています。許可を更新するとすぐには効きません。私は現在のユーザー(ログアウトを意味する)を終了し、再訪問(手段のログイン)ユーザーの許可。春のセキュリティでユーザー権限を更新した後すぐに権限を有効にするにはどうすればいいですか?

春のセキュリティでユーザー権限を更新した後すぐに権限を有効にする方法はありますか?

+0

解決策の1つについては、[リアルタイムでのセキュリティで保護されたセッションの調整](http://spring.io/blog/2009/01/03/spring-security-customization-part-2-adjusting-secured-session-リアルタイムで)ポストをSpring Sourceブログに投稿します。 – Karimchik

+0

それはしばらくかかったが、これは最終的に考え出されたと思う: http://stackoverflow.com/q/23072235/42962 – hooknc

答えて

0

あなたは非常にあなたの問題の正確な詳細を提供しなかったので、私はあなたが状況があるとします。ユーザーはにログインしようとするときは、UserDetailsをロードするUserDetailsS​​erviceを供給している

  1. このサービスの一環として、データベース/ DAOにクエリを発行して、ユーザーのアクセス許可の詳細をロードし、これに基づいて付与された権限を設定しています。
  2. 「権限を更新するとデータベース(またはデータを格納しているもの)のユーザーのアクセス許可を更新することを参照してください。

あなたが見ているのは、意図的なものです.Blue Securityは初めてログインするときにユーザーのUserDetailsを読み込み、それ以降はセッションに保存します。一般的には、アプリケーションが各リクエストのユーザーの詳細について同じクエリを実行する必要がないため、これは意味があります。また、ユーザーのアクセス許可は、訪問の99.9%で一般的に変更されません。

この動作を変更するには、UserDetailsS​​erviceを再クエリし、SecurityContext内のUserDetailsを置き換える、いくつかのコード(書き込みする必要がある)をトリガーする "refresh"コマンド/ページを追加することができます。私はこれを行うための組み込みの方法があるとは思わない。

+0

あなたの仮定は正しいです。私は知っていますre-login.Perhaps私は変更することができます現在のセッションに格納するユーザーのアクセス許可。私はしようとしている.. –

0

GrantedAuthorities []へのアクセスを許可する認証メカニズムから返されるUserDetailsインターフェイスの独自の実装を作成できます。次に、新しい権限をそのUserDetailsオブジェクトに直接追加します。一度に複数のセッションを開くことができる場合(または複数のユーザーが同じ汎用ログインを共有する場合)、変更されたセッションでのみ新しいアクセス許可が表示されます。

3

ガンダルソリューションは有効ですが、完全ではありません。新しいセキュリティ権限(以前は利用できなかったページへのアクセスを許可するなど)は、新しい権限リストを含む新しい認証オブジェクト(新しいUsernamePasswordAuthenticationTokenなど)を作成する必要があります。

7

あなたは99.9%が再認証を必要としないので、あなたが注意を払う必要があります。もちろん、この

<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> 
     <property name="alwaysReauthenticate" value="true"/> 
... 
</bean> 

ようなあなたの AbstractSecurityInterceptorにalwaysReauthenticateを設定することができます。認証ではデータベースなどが使用されるため、パフォーマンスが低下する可能性があります。しかし、通常は、第2レベルの休止状態のようなキャッシュを持っているので、毎回userdetailsをロードすることは、当局が変更されていないすべてのケースでメモリのみの操作でなければなりません。少なくともGoogleのAppEngineのセッションではありません

UserContext userContext = (UserContext) context.getAuthentication().getPrincipal(); 
if (userContext != null && userContext.getUsername() != null) { 
    //This is my function to refresh the user details 
    UserDetailsBean userDetails = getUserDetailsBean(userContext.getUsername()); 
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
    if (authentication instanceof UsernamePasswordAuthenticationToken) { 
     UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication; 
     auth.setDetails(userDetails); 
    } 
    return userDetails; 
} else { 
    throw new ServiceException("User not authenticated"); 
} 
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); 

+1

私は豆のメソッドを保護する場合、別のフィルタに同じ変更を行う必要がありますか、これは十分な? –

+1

このフィルタは、私が見ている限りWebリクエストのみです。 MEthodSecurityInterceptorを使用している場合は、自分でreauthenticateを呼び出すことができます。しかし、すべてのメソッド呼び出しがHTTPリクエストの中にあるので、すべてのメソッド呼び出しの前にこのWebフィルタをチェックしてください。 – Janning

+0

これは正解です。私は、このインターセプタを、セキュリティ設定に、セクションの中の "FILTER_SECURITY_INTERCEPTOR" /> 'またはインターセプタプロパティによって組み込む必要があることを追加したいだけです:' <

-2

あなたはこの

SecurityContextHolder.getContext().setAuthentication(SecurityContextHolder.getContext().getAuthentication()); 
+1

このコードを試しました。残念ながら、それは何の影響もありませんでした。 – chelder

2

を試すことができますが、あなたも、セッションを更新する必要があり、スレッドローカルコンテキストをリセットするには十分ではありません参照を更新し、スレッドのローカルを変更して自動的に更新されない場合は、手動でsession.setオブジェクトを設定する必要があります。

+0

セッション属性の更新でも機能しませんでした –

関連する問題