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