8

@PreAuthorize で保護されたメソッドがあります

@PreAuthorize("hasRole('ROLE_ADMIN') and (#action.userId != principal.id)")
public void execute(EditAction action)

ここで、バックグラウンド タスクからこのメソッドを呼び出す必要があります。このコードを単純に実行すると、例外が発生します。

AuthenticationCredentialsNotFoundException: SecurityContext で認証オブジェクトが見つかりませんでした

必要な認証を SecurityContext に設定する必要があるようです。できます:

  1. バックグラウンド タスク用のカスタム AuthenticationToken を記述します。
  2. 偽のユーザーで UsernamePasswordAuthenticationToken を使用します。
  3. バックグラウンド タスクでセキュリティで保護されたメソッドを使用しないでください。
  4. 他の推奨事項はありますか?

正しい方法は何ですか?

4

2 に答える 2

2

現在のスレッドとセッション(Webアプリケーションで使用されている場合)に自分で認証トークンを登録できます。

SecurityContextHolder.getContext().setAuthentication(token);
session.put(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());

適切なロールを追加する限り、これには標準のUsernamePasswordAuthenticationTokenを使用できます。

于 2012-04-26T11:13:56.893 に答える
2

この場合、手動の回避策がオプションです。

(1)これが独立した仕事であれば、

保護されたメソッドが呼び出される前に、Authentication オブジェクトを作成し、それをセキュリティ コンテキストに設定します。セキュリティで保護されたメソッドの実行が完了したら、セキュリティ コンテキストから Authentication オブジェクトを削除します。

public final class AuthenticationUtil {

//Ensures that this class cannot be instantiated
private AuthenticationUtil() {
}

public static void clearAuthentication() {
    SecurityContextHolder.getContext().setAuthentication(null);
}

public static void configureAuthentication(String role) {
    Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(role);
    Authentication authentication = new UsernamePasswordAuthenticationToken(
            "user",
            role,
            authorities
    );
    SecurityContextHolder.getContext().setAuthentication(authentication);
}

だからそれは次のようになります

AuthenticationUtil.configureAuthentication(role);
// Call to the secured method 
AuthenticationUtil.clearAuthentication();

(2) 認証オブジェクトを null にできない Web アプリケーションの場合は、呼び出さないでください。

AuthenticationUtil.configureAuthentication(role);
// call to the secured method 
于 2019-09-25T15:01:11.827 に答える