5

Spring Security 3.1 を使用して Web サイトのユーザーを認証しています。Spring Security がデータベースに接続できないためにログインが失敗すると、ログに次のステートメントが表示されます。

2012-07-12 11:42:45,419 [ajp-bio-8009-exec-1] DEBUG      org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!

私の質問は、なぜこれが ERROR ではなく DEBUG ステートメントなのですか? 実際のエラーを見つけるためだけに、大量のデバッグ ステートメントを調べなければなりません。

編集

これが私の認証マネージャーです:

<bean id="securityDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/securityDS"/>
    <property name="resourceRef" value="true"/>
</bean>

<bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder" />

<security:authentication-manager>
    <security:authentication-provider>
        <security:password-encoder ref="encoder" />
        <security:jdbc-user-service 
            data-source-ref="securityDataSource"
            authorities-by-username-query="SELECT username, authority FROM login WHERE username = ?"
            users-by-username-query="SELECT username, password, enabled FROM login WHERE username = ?"
        />        
    </security:authentication-provider>
</security:authentication-manager>
4

2 に答える 2

8

そのメッセージは次のように出力されますAbstractAuthenticationProcessingFilter.unsuccessfulAuthentication:

protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException failed) throws IOException, ServletException {
    SecurityContextHolder.clearContext();

    if (logger.isDebugEnabled()) {
        logger.debug("Authentication request failed: " + failed.toString());

ユーザー入力に基づくものを含め、認証が失敗する原因はいくつかあります。たとえば、 では、ユーザー名が見つからない場合AbstractUserDetailsAuthenticationProvider.authenticateに aがスローされる可能性があります。BadCredentialsException

        try {
            user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
        } catch (UsernameNotFoundException notFound) {
            logger.debug("User '" + username + "' not found");

            if (hideUserNotFoundExceptions) {
                throw new BadCredentialsException(messages.getMessage(
                        "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
            } else {
                throw notFound;
            }
        }

認証が失敗する正当な理由がある可能性があるためAbstractAuthenticationProcessingFilter、エラーをログに記録することは意味がありません。システム エラーが発生した場合、エラーはさらに下流に記録されているはずです。

問題があると思われDaoAuthenticationProviderます(インラインのコメントを参照してください):

protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
        throws AuthenticationException {
    UserDetails loadedUser;

    try {
        loadedUser = this.getUserDetailsService().loadUserByUsername(username);
    }
    catch (DataAccessException repositoryProblem) {
        // *** ERROR SHOULD BE LOGGED HERE ***
        throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
    }

おそらくエラーがここに記録されるはずです - Spring で JIRA をログに記録して、それを要求できます。たぶん彼らは、誰もがカスタムを提供し、UserDetailsServiceそこで独自の例外をキャッチ/ログするだろうと想定しています. 使用している場合は使用JdbcDaoImplしません。JdbcDaoImplは例として意図されており、堅牢ではないと思います。ドキュメントごと:

幸いなことに、インメモリ マップを使用するもの (InMemoryDaoImpl) や JDBC を使用するもの (JdbcDaoImpl) など、多数の UserDetailsS​​ervice 実装が提供されています。ただし、ほとんどのユーザーは、従業員、顧客、またはアプリケーションの他のユーザーを表す既存のデータ アクセス オブジェクト (DAO) の上に実装するだけで、独自の実装を作成する傾向があります。

于 2012-07-13T00:54:22.550 に答える