1

spring.security.version=3.1.0.RELEASEを使用しています。私が抱えている問題は、何らかの理由でAuthenticationFailureCredentialsExpiredEventが発生しないことです。

コードのデバッグ中に、AbstractUserDetailsAuthenticationProviderがコンソールに「ユーザーアカウントのクレデンシャルの有効期限が切れています」と表示することがわかりました。しかし、問題のイベントがトリガーされない理由については、まだ困惑しています。

これが私のコードです:

class JpaUserDetails implements UserDetails {
...
...
   @Override
   public boolean isCredentialsNonExpired() {
       if (some logic) {
           return true;
       }
       else {
           return false;
       }
   }
}

次のSpringコードの行から、AbstractUserDetailsAuthenticationProviderがコンソールに「ユーザーアカウントの資格情報の有効期限が切れています」と表示されています。

public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitilizeBean, MessageSourceAware {
...
...
    private class DefaultPostAuthenticationChecks implements UserDetailsChecker {
        public void check(UserDetails user) {
            if(!user.isCredentialsNonExpired()) {
                logger.debug("User account credentials have expired");
                throw new CredentialsExpiredException(message.getMessage(
                          "AbstractUserDetailsAuthenticationProvider.credentialsExpired",
                          "User credentials have expired"), user);
            }
        }
    }
}

問題は、ユーザークレデンシャルの有効期限が切れると、Springが次の方法で処理しているイベントAuthenticationFailureCredentialsExpiredEventを生成することを期待していることです。

class SecurityEventDispatcher implements ApplicationListener<ApplicationEvent> {
    final List<SecurityEventListener> listeners = new ArrayList<SecurityEventListener>();

    public void registerListener(SecurityEventListener listener) {
        this.listener.add(listener);
    }

    public void onApplicationEvent(ApplicationEvent event) {
        for (SecurityEventListener listener : this.listeners) {
            if(listener.canHandle(event)) {
                listener.handle(event);
            }
        }
    }
}

これは私がログイン失敗イベントを処理する方法です:

public class LoginFailedEvent extends SecurityEventListener {

    @Override
    public boolean canHandle(Object event) {
        if(event instanceof AbstractAuthenticationFailureEvent) {
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    public void handle(Object event) {
        if (event instanceof AuthenticationFailureBadCredentialsEvent) {
            // do something
        }

        if (event instanceof AuthenticationFailureCredentialsExpiredEvent) {
            // do something
        }
    }
}

前に述べたように、AuthenticationFailureCredentialsExpiredEventが発生しないという問題があります。正常に動作するAuthenticationFailureBadCredentialsEventをテストしました。

これは私が悪い資格情報のためにイベントで得るものです:(これはうまく機能しています)

org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent

これは、パスワードの有効期限が切れた場合に発生するものです。

ServletRequestHandledEvent:url = [/ app / loginFailure] with failureCause = null

誰かが何が間違っている可能性があるか考えていますか?どんな助けでも大歓迎です。

4

2 に答える 2

1

この問題が発生している場合は、Spring セキュリティを 3.1.2 または + にアップグレードするだけで、問題は修正されます。

于 2013-05-21T21:05:42.217 に答える
1

この問題に関する文献はあまりないため、この質問に対する回答を次に示します。

おそらく、ProviderManager の eventPublisher を NullEventPublisher 以外に設定する必要があります。タグを介してこれを行う簡単な方法はないため、標準の Bean 構成を使用して AuthenticationProvider を作成し、それを ProviderManager の標準の Spring Bean に注入する必要があります。

Rob Winch - Spring セキュリティ リード

于 2013-02-14T22:52:05.427 に答える