Java 财产';密码编码器';在春季安全中引发异常

Java 财产';密码编码器';在春季安全中引发异常,java,spring,spring-mvc,spring-security,Java,Spring,Spring Mvc,Spring Security,在我的web应用上部署时,我遇到此错误 Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframewo

在我的web应用上部署时,我遇到此错误

    Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name
    'org.springframework.security.filterChains': Cannot resolve reference to bean 
    'org.springframework.security.web.DefaultSecurityFilterChain#1' while setting bean property
    'sourceList' with key [1]; nested exception is 
     org.springframework.beans.factory.BeanCreationException: Error creating bean with name
    'org.springframework.security.web.DefaultSecurityFilterChain#1': Cannot resolve      reference to bean 
   'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0'
    while setting constructor argument with key [3]; nested exception is 
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name
    'org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0': 
    Cannot resolve reference to bean 'org.springframework.security.authentication.ProviderManager#0' while setting bean property
   'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name
    'org.springframework.security.authentication.ProviderManager#0': Cannot resolve reference to bean
    'org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0' while setting constructor argument; nested exception is 
   org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0': 
 FactoryBean threw exception on object creation; nested exception is 
 org.springframework.beans.factory.BeanCreationException: Error creating bean with name
 'org.springframework.security.authenticationManager': Cannot resolve reference to bean 
 'org.springframework.security.authentication.dao.DaoAuthenticationProvider#0' while
 setting constructor argument with key [0]; nested exception is 
 org.springframework.beans.factory.BeanCreationException: Error creating bean with name
 'org.springframework.security.authentication.dao.DaoAuthenticationProvider#0': Error 
  setting property values; nested exception is 
 org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:

PropertyAccessException 1: org.springframework.beans.MethodInvocationException:
Property 'passwordEncoder' threw exception; nested exception is java.lang.NullPointerException

        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:326)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:350)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:154)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1417)
我的spring-security.xml

<authentication-manager>
            <authentication-provider user-service-ref="customUserDetailsService">
                    <password-encoder ref="customEnocdePassword" >
                        <salt-source user-property="email"/>
                    </password-encoder>
            </authentication-provider>
    </authentication-manager>  


    <beans:bean id="customEnocdePassword" class="com.mycom.myproject.service.impl.service.impl.CustomEnocdePassword" />
    <beans:bean id="exceptionMapper" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler" >
而customUserDetailsService.java是

@Service
@Transactional(readOnly = true)
public class CustomUserDetailsService extends CommonService implements UserDetailsService {

    static final Logger logger = Logger.getLogger(CustomUserDetailsService.class);

    @Resource(name="userService")
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String email)
            throws UsernameNotFoundException, DataAccessException {
        UserDetailedBean domainUser = null;


            try {




                domainUser = userService.getUserByName(email);      

                //userService.getUserDetailFromSpringSecurity();




                domainUser.isEnabled();
                domainUser.isAccountNonExpired();
                domainUser.isCredentialsNonExpired();
                domainUser.isAccountNonLocked();


        //Collection<? extends GrantedAuthority> roles =  getAuthorities((long) domainUser.getRoleId());



        } catch (AccountStatusException e) {
            logger.error("Invalid Login. "+email,e);
            throw new RuntimeException(e);
        } catch (TrialPeriodException e) {
            e.printStackTrace();
        }  catch (LoginException e) {
            throw new UsernameNotFoundException("Username not found. Please try again.");
        }

            return domainUser;
    }

    /**
     * Retrieves a collection of {@link GrantedAuthority} based on a numerical role
     * @param role the numerical role
     * @return a collection of {@link GrantedAuthority
     */
    public static final Collection<? extends GrantedAuthority> getAuthorities(Long role) {
        List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
        return authList;
    }


    /**
     * Converts a numerical role to an equivalent list of roles
     * @param role the numerical role
     * @return list of roles as as a list of {@link String}
     */
    public static List<String> getRoles(Long role) {
        List<String> roles = new ArrayList<String>();

        if (role.intValue() == 1) {
            roles.add("ROLE_USER");
            roles.add("ROLE_ADMIN");
            roles.add("ROLE_SJADMIN");          
        } else if (role.intValue() == 2) {
            roles.add("ROLE_USER");
            roles.add("ROLE_ADMIN");
        }else if (role.intValue() == 3) {
            roles.add("ROLE_USER");
            roles.add("ROLE_ADMIN");
        }else{
            roles.add("ROLE_USER");
        }

        return roles;
    }

    /**
     * Wraps {@link String} roles to {@link SimpleGrantedAuthority} objects
     * @param roles {@link String} of roles
     * @return list of granted authorities
     */
    public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        return authorities;
    }

}
@服务
@事务(只读=真)
公共类CustomUserDetailsService扩展CommonService实现UserDetailsService{
静态最终记录器=Logger.getLogger(CustomUserDetailsService.class);
@资源(name=“userService”)
私人用户服务;
@凌驾
公共用户详细信息loadUserByUsername(字符串电子邮件)
抛出UsernameNotFoundException、DataAccessException{
UserDetailedBean域用户=null;
试一试{
domainUser=userService.getUserByName(电子邮件);
//getUserDetailFromSpringSecurity();
domainUser.isEnabled();
domainUser.isAccountNoExpired();
domainUser.isCredentialsNonExpired();
domainUser.isAccountNonLocked();

//收集我认为CustomEnocdePassword中的以下代码导致了您的问题:

if(username.equals(null)){
  throw new IllegalArgumentException("Username cannot be null");
}
换成

if(username==null)){
  throw new IllegalArgumentException("Username cannot be null");
}
根据堆栈跟踪,spring在设置
DaoAuthenticationProvider
bean的
passwordEncoder
属性时遇到NPE。如果您查看该方法,您将看到它调用
passwordEncoder.encodePassword(用户未找到密码,null);
,这会导致当前代码中出现空指针


还请注意,
org.springframework.security.authentication.encoding.PasswordEncoder
现在已被弃用。

我解决了这个问题,因为spring和spring安全性中存在一些冲突,所以我必须从spring中排除spring安全性,并单独添加spring安全性

我猜
userService
来自CUSTOMUSERDETAILSSSERVICE为null,但我不确定。堆栈跟踪中没有更多的行可以显示哪一行抛出NPE吗?谢谢Andrei,我解决了这个问题,因为spring和spring安全性中存在一些冲突,所以我必须从spring中排除spring安全性,并单独添加spring安全性。您可以添加m吗关于哪个jar与其他jar冲突的详细信息?您是否必须更改以实现新的
PasswordEncoder
Hi Jigar,我在问题中添加了我的Pom.xml。我使用了不同版本的spring安全性和适用于meThanks的spring更新,在我的情况下,它调用了
encodePassword()
salt为空,这就是为什么它失败的原因,在升级Hi Jigar之后,我更新了我的spring-security.xml。希望这能有所帮助。
<?xml version="1.0" encoding="UTF-8"?>
  <beans:beans xmlns="http://www.springframework.org/schema/security"
 xmlns:beans="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:p="http://www.springframework.org/schema/p" 
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security 
    http://www.springframework.org/schema/security/spring-security.xsd
    http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util.xsd">
<http pattern="/resources" security="none" />



<http auto-config="true"  use-expressions="true">
    <intercept-url pattern="/login.htm" access="permitAll"/>
    <intercept-url pattern="/logout.htm" access="permitAll"/>
    <intercept-url pattern="/forgotPasswordForm" access="permitAll"/>
    <intercept-url pattern="/registrationForm" access="permitAll"/>     
    <intercept-url pattern="/home.htm" access="hasRole('ROLE_USER')"/>




    <form-login login-page="/login.htm" 
                authentication-failure-url="/loginfailed"
                default-target-url="/index.htm" 
                always-use-default-target="false"
                />

    <access-denied-handler error-page="/logout.htm"/>

    <logout invalidate-session="true" 
        logout-url="/logout.htm"
        success-handler-ref="userController"/>
        <remember-me data-source-ref="datasource" />
    <!--<remember-me user-service-ref="customUserDetailsService" key="89dqj219dn910lsAc12" use-   secure-cookie="true"  token-validity-seconds="466560000"/>-->
 <session-management session-authentication-strategy-ref="sas"/>
</http>





  <authentication-manager>
        <authentication-provider user-service-ref="customUserDetailsService">
                <password-encoder ref="customEnocdePassword" >
                    <salt-source user-property="email"/>
                </password-encoder>
        </authentication-provider>
</authentication-manager>  

 <!-- <beans:bean id="expirationChecker" class="com....service.impl.utility.UserTrialPeriodExpirationChecker" />  -->
<beans:bean id="customEnocdePassword" class="com....service.impl.service.impl.CustomEnocdePassword" />
<beans:bean id="exceptionMapper" class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler" >
<beans:property name="exceptionMappings">
    <beans:map>
        <beans:entry key="com....exception.TrialPeriodExpiredException" value="/pricing"/>
        <beans:entry key="com....service.impl.exception.LoginException" value="/login?message=Invalid login"/>
    </beans:map>
</beans:property>
</beans:bean>

<beans:bean id="sas"
    class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="maximumSessions" value="3" />
if(username.equals(null)){
  throw new IllegalArgumentException("Username cannot be null");
}
if(username==null)){
  throw new IllegalArgumentException("Username cannot be null");
}