spring-security フレームワークを使用しています。権限を更新しても、すぐには有効になりません。現在のユーザーを終了する必要があり(ログアウトを意味します)、再度アクセスする(ログインを意味します)ことで、ユーザーの権限が更新されます。 .
春のセキュリティでユーザー権限を更新したらすぐに権限を有効にする方法はありますか?
spring-security フレームワークを使用しています。権限を更新しても、すぐには有効になりません。現在のユーザーを終了する必要があり(ログアウトを意味します)、再度アクセスする(ログインを意味します)ことで、ユーザーの権限が更新されます。 .
春のセキュリティでユーザー権限を更新したらすぐに権限を有効にする方法はありますか?
このようにAbstractSecurityInterceptorで alwaysReauthenticate を設定できます
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="alwaysReauthenticate" value="true"/>
...
</bean>
もちろん、再認証は 99.9% 必要ないので注意が必要です。認証はデータベースなどを使用する可能性があるため、パフォーマンスが低下する可能性があります。ただし、通常、休止状態の第 2 レベルのようにキャッシュがあるため、権限が変更されていない場合は常に、ユーザーの詳細を毎回ロードするのはメモリのみの操作である必要があります。
ガンダルフのソリューションは有効ですが、完全ではありません。新しいアクセス許可がスプリング セキュリティによって考慮されるようにするには (例: 以前は利用できなかったページへのアクセスを許可する)、権限の新しいリストを含む新しい認証オブジェクト (例: 新しい UsernamePasswordAuthenticationToken) を作成する必要があります。
次のスレッドは、リクエストごとにユーザー/プリンシパルをリロードする方法を説明しています:
Spring Security でリクエストごとにデータベースから UserDetails オブジェクトをリロードする
完全な開示私は、上記のリンクの質問と回答の著者です。
Thread Local コンテキストをリセットするには不十分です。セッションも更新する必要があります。
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());
少なくとも Google appengine では、セッションは参照ではなく、スレッド ローカルを変更しても自動的に更新されないため、オブジェクトを手動で session.set する必要があります。
質問で正確な詳細を提供しなかったため、次のような状況にあると思います。
その場合、表示されているのは設計によるものです。Spring Security は、ユーザーがログインを試みたときに初めて UserDetails をロードし、それ以降はそれを Session に保存します。アプリケーションが各リクエストでユーザーの詳細について同じクエリを実行する必要がなくなるため、通常、これは理にかなっています。また、ユーザーのアクセス許可は通常、訪問の 99.9% を通じて変更されません。
この動作を変更するには、UserDetailsService を再クエリし、SecurityContext の UserDetails を置き換えるコード (作成する必要があります) をトリガーする「更新」コマンド/ページをどこかに追加することを検討することをお勧めします。これを行うための組み込みの方法はないと思います。
GrantedAuthorities[] へのアクセスを許可する、認証メカニズムから返される UserDetails インターフェイスの独自の実装を作成できます。次に、新しい権限をその UserDetails オブジェクトに直接追加します。ユーザーが一度に複数のセッションを開くことができる場合 (または複数のユーザーが同じ一般的なログインを共有している場合)、変更したセッションでのみ新しいアクセス許可が表示されるという問題が発生する可能性があります。
これを試すことができます
SecurityContextHolder.getContext().setAuthentication(SecurityContextHolder.getContext().getAuthentication());