Конфигурация Spring Security 4 xml Аутентификация UserDetailsService не работает

Я знаю, что этот вопрос задавали много раз, но любой ответ решил мою проблему. Я пытаюсь реализовать пользовательскую форму входа в систему, используя Spring Security 4 + Hibernate + Spring Data Jpa, но все работает не так, как я ожидаю.

Когда я использую учетные данные в памяти, все работает нормально, но вместо этого я хочу использовать свою базу данных.

Под основным кодом:

Конфигурация безопасности XML.

    <beans:bean id="encodeurMotDePasse" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
        <beans:constructor-arg name="strength" value="12" />
    </beans:bean>

    <security:http auto-config="true" create-session="never">
        <security:intercept-url pattern="/" access="permitAll" />
        <security:intercept-url pattern="/inscription**" access="hasRole('ADMIN') or hasRole('USER')" />
        <security:intercept-url pattern="/connexion**" access="hasRole('USER') or hasRole('USER')" />
        <security:intercept-url pattern="/test**" access="hasRole('ADMIN')" />
        <security:intercept-url pattern="/dba**" access="hasRole('ADMIN')" />
        <security:form-login login-page="/login.html"
                             username-parameter="identifiant" 
                             password-parameter="motDePasse"
                             authentication-failure-url="/login.html?error=t"/>

    </security:http>

    <beans:bean id="customUserDetailsService" class="com.app.security.CustomUserDetailsService"/>
     <security:authentication-manager >
        <security:authentication-provider user-service-ref ="customUserDetailsService">
             <security:password-encoder ref="encodeurMotDePasse" />
        </security:authentication-provider> 
    </security:authentication-manager>

Реализация UserDetailsService:

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private ServicesDAO service;

    @Override
    public UserDetails loadUserByUsername( String username ) throws UsernameNotFoundException {

    T_authentification userPrincipals = service.getAuthenticatePrincipal( username );

    if ( userPrincipals == null ) {
        System.out.println( "user inexistant" );
        throw new UsernameNotFoundException( "L'utilisateur n'a pas été trouvé" );
    } else {
        System.out.println( "user trouvé" );
    }

    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

    for ( T_roles role : userPrincipals.getRoles() ) {
        System.out.println( " role dans userdetails service est :" + role.getRoleName() );
        authorities.add( new SimpleGrantedAuthority( role.getRoleName() ) );
    }

    // return new CustomUserDetails( userPrincipals );
    return new org.springframework.security.core.userdetails.User( userPrincipals.getUsername(), userPrincipals.getMotDePasse(), authorities );
 }
}

Когда я тестирую код в методе контроллера, все учетные данные хорошо загружаются из базы данных, и я могу распечатать их на консоли.

Другая проблема заключается в том, что при сбое входа в систему Spring Security не отправляет никакого отладочного сообщения в консоль, чтобы указать причину этого сбоя.

ИЗМЕНИТЬ

Вот мой log4j.xml, я слежу за конфигурацией, но в консоли появляется какое-либо сообщение, и файл также пуст.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE log4j:configuration PUBLIC  "-//APACHE//DTD LOG4J 1.2//EN"    "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">

    <appender name="Appender1" class="org.apache.log4j.ConsoleAppender">
        <param name="Threshold" value="debug" />
       <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%-7p %d [%t] %c %x - %m%n"/>
       </layout>
    </appender>

  <appender name="SpringAppender" class="org.apache.log4j.FileAppender"> 
        <param name="file" value="C:/Log4j/Spring-details.log" /> 
        <param name="Threshold" value="debug" />
        <param name="append" value="true" /> 
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                value="%d{MM/dd/yyyy HH:mm:ss}  [%t]:%c{5}.%M()%L %m%n" />
        </layout>
    </appender>

    <appender name="Appender2" class="org.apache.log4j.FileAppender">
       <param name="File" value="C:/Log4j/app.log" />
       <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%-7p %d [%t] %c %x - %m%n"/>
       </layout>
    </appender>

     <category name="org.springframework">
        <priority value="ALL" />
    </category>


    <category name="org.springframework">
        <priority value="debug" />
    </category>

    <category name="org.springframework.beans">
        <priority value="debug" />
    </category>

    <category name="org.springframework.security">
        <priority value="debug" />
    </category>

    <category
        name="org.springframework.beans.CachedIntrospectionResults">
        <priority value="debug" />
    </category>

    <category name="org.springframework.jdbc.core">
        <priority value="debug" />
    </category>

    <category name="org.springframework.transaction.support.TransactionSynchronizationManager">
        <priority value="debug" />
    </category>

    <logger name="org.springframework" additivity="false">
        <level value="DEBUG"/>
        <appender-ref ref="SpringAppender"/>
    </logger>

    <root>
     <!--         <priority value="INFO"/> -->
        <level value="DEBUG"/>
        <appender-ref ref="Appender1" />
        <appender-ref ref="SpringAppender" />
        <appender-ref ref="Appender2" />
    </root>
</log4j:configuration> 

ИЗМЕНИТЬ2

Я получил это исключение, когда пытаюсь @Autowire этот bean-компонент <beans:bean id="customUserDetailsService" class="com.app.security.CustomUserDetailsService"/> в классе Java.

Почему возникла эта ошибка?

ERROR javax.enterprise.web.core - ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'inscriptionController': Unsatisfied dependency expressed through field 'customUserDetailsService'; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'customUserDetailsService' is expected to be of type 'com.app.security.CustomUserDetailsService' but was actually of type 'com.sun.proxy.$Proxy323' at org.apache.catalina.core.StandardContext.start(StandardContext.java:5985)

Большое спасибо за ваши разъяснения и извините за мой плохой английский.


person akuma8    schedule 25.12.2016    source источник
comment
удалите authentication-failure-url="/login.html?error=t"/>, исключение вернется сразу, тогда вы можете опубликовать ошибку здесь, и что такое encodeurMotDePasse для passwordEncoder?   -  person chaoluo    schedule 25.12.2016
comment
Я прокомментировал authentication-failure-url="/login.html?error=t", но в консоли ничего не появилось. encodeurMotDePasse — это мой bean-компонент BCryptPasswordEncoder.   -  person akuma8    schedule 25.12.2016
comment
исключение вернется в ответ, а не в консоль. или вы можете включить журнал на уровне отладки.   -  person chaoluo    schedule 26.12.2016
comment
Как включить журнал? У меня есть log4j.xml в пути к классам, как я могу его включить?   -  person akuma8    schedule 26.12.2016
comment
вы можете найти его в stackoverflow. И какое сообщение об ошибке в ответ?   -  person chaoluo    schedule 26.12.2016
comment
Я редактирую и добавляю конфигурацию log4j.xml.   -  person akuma8    schedule 26.12.2016
comment
добавить <security:debug/> в конфигурацию безопасности. Кстати, Spring Security использует общий журнал, и если вы хотите перейти на SLF4J (log4j или logback), следуйте этому документ   -  person chaoluo    schedule 26.12.2016
comment
Я добавил <security:debug/>, перешел по ссылке, чтобы добавить SLF4J + Log4J, и скопировал информацию здесь, но все еще имею ту же проблему .   -  person akuma8    schedule 28.12.2016
comment
Уже 3 дня, а решения не нахожу :(!   -  person akuma8    schedule 28.12.2016
comment
почему create-session="never" для входа в форму, не могли бы вы загрузить свой простой проект на github?   -  person chaoluo    schedule 28.12.2016
comment
create-session="never" чтобы избежать создания сеанса фреймворком, я хочу сделать это сам. Я добавляю свой проект в github, как вы просили, он находится в разработке, поэтому он немного грязный . Мне нужна помощь, потому что я полностью застрял. Большое спасибо.   -  person akuma8    schedule 29.12.2016
comment
<form-login ... authentication-failure-handler-ref="failureHandler" ... /> <bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" /> это отправит сообщение об ошибке в ответ напрямую.   -  person chaoluo    schedule 29.12.2016
comment
Я добавил это, но это ничего не изменило. Я также добавил аутентификацию jdbc-user-service, и она работает хорошо. Поэтому я не знаю, почему не работает только UserDetailsService. Больше всего расстраивает то, что я не вижу сообщения об ошибке после сбоя регистрации.   -  person akuma8    schedule 29.12.2016
comment
Еще одна идея? большое спасибо   -  person akuma8    schedule 29.12.2016
comment
Я не могу найти никакой конфигурации для сканирования com.chicowa.services, но ваш userDetailService зависит от этого.   -  person chaoluo    schedule 30.12.2016
comment
В файле «/WEB-INF/spring/servlet-config.xml» я сканирую все пакеты, подобные этому «context:component-scan base-package=com.chicowa /›», я помещаю пакет явно, чтобы увидеть, это что-то меняет.   -  person akuma8    schedule 30.12.2016
comment
Привет, я вернулся, потому что еще не решил свою проблему :(! Теперь я вижу сообщение журнала, отправленное Spring Security, и кажется, что метод, который загружает данные из базы данных, отправляет NULL. Я не знаю, почему в в других классах этот же метод работает нормально, а не в классе, который реализует UserDetailsService. Кажется, что «@Autowired» здесь @Autowired private ServicesDAO service; не работает должным образом. Любое предложение? Спасибо   -  person akuma8    schedule 06.01.2017
comment
что вы имеете в виду, кажется, что метод, который загружает данные из базы данных, отправляет NULL? и не могли бы вы опубликовать журнал?   -  person chaoluo    schedule 06.01.2017
comment
Я имею в виду, что когда я вызвал свой метод ServicesDAO (service.getAuthenticatePrincipal( username );) для загрузки данных из базы данных, результат был null. Я нашел причину такого странного поведения (для меня это странно) смотрите ответ.   -  person akuma8    schedule 06.01.2017
comment
Я решил основную проблему, но теперь, когда я хочу @Autowired bean-компонент, определенный в spring-security.xml в классе .java, у меня есть исключение (см. EDIT2)   -  person akuma8    schedule 06.01.2017


Ответы (1)


Я нашел причину этого странного поведения.

Я предполагаю, что прослушиватель безопасности spring org.springframework.security.web.session.HttpSessionEventPublisher не использует тот же контекст, что и диспетчер сервлетов. Таким образом, все bean-компоненты, определенные в контексте mvc, недоступны для части безопасности.

Чтобы решить эту проблему, мне пришлось добавить <context:component-scan base-package=.... в корневой контекст, так как все бины, определенные здесь, доступны везде.

Я потерял 2 недели, чтобы найти причину моей проблемы :( !

person akuma8    schedule 06.01.2017