Spring Security 4 xml配置UserDetailsService身份验证不起作用
Posted
技术标签:
【中文标题】Spring Security 4 xml配置UserDetailsService身份验证不起作用【英文标题】:Spring Security 4 xml configuration UserDetailsService authentication not working 【发布时间】:2017-05-10 07:46:45 【问题描述】:我知道这个问题被问了很多次,但任何答案都解决了我的问题。 我正在尝试使用 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="%dMM/dd/yyyy HH:mm:ss [%t]:%c5.%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>
EDIT2
当我在 java 类中尝试 @Autowire
这个 bean <beans:bean id="customUserDetailsService" class="com.app.security.CustomUserDetailsService"/>
时遇到了这个异常。
为什么会出现这个错误?
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
?
我评论了authentication-failure-url="/login.html?error=t"
,但控制台中没有出现任何内容。 encodeurMotDePasse
是我的 'BCryptPasswordEncoder' bean。
异常会返回响应,而不是控制台。或者您可以将日志启用到调试级别。
如何启用日志?我在类路径中有一个 log4j.xml 如何启用它?
你可以在***上搜索它。响应的错误信息是什么?
【参考方案1】:
我找到了这种奇怪行为的原因。
我认为 spring 安全侦听器org.springframework.security.web.session.HttpSessionEventPublisher
不与 servlet 调度程序共享相同的上下文。因此,在 mvc 上下文中定义的所有 bean 对于安全部分都是不可访问的。
为了解决这个问题,我必须在根上下文中添加 <context:component-scan base-package=....
,因为此处定义的所有 bean 都可以在任何地方访问。
我花了 2 周时间才找到问题的原因 :( !
【讨论】:
以上是关于Spring Security 4 xml配置UserDetailsService身份验证不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security 4 xml配置UserDetailsService身份验证不起作用
Spring Boot中Spring Security的XML配置