BadCredentialsException是spring-security

时间:2013-05-01 13:58:00

标签: java authentication spring-security

继续我的项目我在Spring setsurity的帐户授权中遇到了问题 - 查询数据库时出现问题,所有设置都正确,数据库是在项目开始时创建的,调试中没有错误,但是在日志中弹出登录消息:

(UserAuthentication.java:authenticate:56) tradeManager.DAO.Impl.CustomHibernateDaoSupport.find(CustomHibernateDaoSupport.java:60)
        tradeManager.service.authentication.UserAuthentication.authenticate(UserAuthentication.java:45)

...
Authentication request failed: org.springframework.security.authentication.BadCredentialsException: 
User does not exists!

我添加了一些捕获来获得精确异常并获得新的NullPointerException

17:52:34.280:WARN::/tradeManager/j_spring_security_check
java.lang.NullPointerException
    at tradeManager.DAO.Impl.CustomHibernateDaoSupport.find(CustomHibernateDaoSupport.java:60)
    at tradeManager.service.authentication.UserAuthentication.authenticate(UserAuthentication.java:48)

有人可以解释一下我做错了什么吗?请帮帮我。

这是受查询影响的代码:

@Service("userAuthentication")
public class UserAuthentication implements AuthenticationManager {

protected static Logger userAccessLogger = Logger.getLogger("userAccessLog");
private UserDAO userDAO = new UserDAOImpl();
private Md5PasswordEncoder passwordEncoder = new Md5PasswordEncoder();

public Authentication authenticate(Authentication auth)
        throws UsernameNotFoundException {

    User user = null;

    /*
     * Init a database user object
     */
    try {
        // Retrieve user details from database
        //user = userDAO.find(auth.getName());
        List<User> list = userDAO.findAllByParam("username", auth.getName());
        user = (list.isEmpty()) ? null :  list.get(0);

    } catch (Exception e) {

        StackTraceElement[] stack = e.getStackTrace();
        String exception = "";
        for (StackTraceElement s : stack) {
            exception = exception + s.toString() + "\n\t\t";
        }
        userAccessLogger.error(exception);

        throw new BadCredentialsException("\n\tUser " + auth.getName() + " does not exists!\n");
    }

    /*
     * Compare passwords
     * Make sure to encode the password first before comparing
     */
     if (user != null) {
        if (passwordEncoder.isPasswordValid(user.getPassword(), (String) auth.getCredentials(), null)) {
            throw new BadCredentialsException("\n\tWrong password!\n");
        }
    }

    /*
     * main logic of authentication manager
     * Username and password must be the same to authenticate
     */
    if (auth.getName().equals(auth.getCredentials())) {
        throw new BadCredentialsException("Entered username and password are the same!");

    } else {
        assert user != null;
        return new UsernamePasswordAuthenticationToken(
                auth.getName(),
                auth.getCredentials(),
                getAuthorities(user.getAccess()));
    }
}

/*
 * Retrieves the correct ROLE type depending on the access level
 */
public Collection<GrantedAuthority> getAuthorities(Integer access) {
    // Create a list of grants for this user
    List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(2);

    userAccessLogger.debug("Grant ROLE_USER to this user");
    authList.add(new SimpleGrantedAuthority("ROLE_USER"));

    if (access.compareTo(1) == 0) {
        authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        userAccessLogger.debug("Grant ROLE_ADMIN to this user");
    }

    // Return list of granted authorities
    return authList;
}

这里是CustomHibernateDaoSupport:

public class CustomHibernateDaoSupport<T> implements DAO<T> {
protected static Logger daoSupportLogger = Logger.getLogger("daoSupportLog");
private Class<T> clazz;
private SessionFactory sessionFactory;

public CustomHibernateDaoSupport(Class<T> clazz) {
    this.clazz = clazz;
}

@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}

private SessionFactory  getSessionFactory() {
    return sessionFactory;
}

@Override
@Transactional
public void save(T entity) {
    getSessionFactory().getCurrentSession().save(entity);
}

@Override
@Transactional
public void update(T entity) {
    getSessionFactory().getCurrentSession().update(entity);
}

@Override
@Transactional
public void delete(Serializable key) {
    Object entity = getSessionFactory().getCurrentSession().get(clazz, key);
    if (entity != null) {
        getSessionFactory().getCurrentSession().delete(entity);
    }
}

@Override
@Transactional
public T find(Serializable key) {
    return (T) getSessionFactory().getCurrentSession().get(clazz, key);
}

@Override
@Transactional
public List<T> findAll() {
    return getSessionFactory().getCurrentSession().createCriteria(clazz).list();
}

@Override
@Transactional
public List<T> findAllByParam(final String paramName, final Object paramValue) {
    return getSessionFactory().getCurrentSession().createCriteria(clazz)
            .add(Restrictions.eq(paramName, paramValue))
            .list();
}
}

安全设置如下:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:security="http://www.springframework.org/schema/security"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:p="http://www.springframework.org/schema/p"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/security
            http://www.springframework.org/schema/security/spring-security-3.1.xsd">



<!-- excluded from Security
<security:http pattern="/resources/*" security="none" />-->

<!-- Configuration of Spring-Security. Set to false to assign custom filters  -->

<security:http auto-config="false" use-expressions="true" access-denied-page="/crimea/auth/denied"
               entry-point-ref="authenticationEntryPoint" >

    <security:logout invalidate-session="true"
                    logout-success-url="/crimea/auth/login"
                    delete-cookies="SPRING_SECURITY_REMEMBER_ME_COOKIE"
                    logout-url="/crimea/auth/logout"/>

    <security:intercept-url pattern="/crimea/auth/login" access="permitAll"/>
    <security:intercept-url pattern="/crimea/main/admin" access="hasRole('ROLE_ADMIN')"/>
    <security:intercept-url pattern="/crimea/main/common" access="hasRole('ROLE_ADMIN','ROLE_USER')"/>

    <security:custom-filter ref="authenticationFilter" position="FORM_LOGIN_FILTER"/>

</security:http>

<!-- Custom filter for username and password -->
<bean id="authenticationFilter"
      class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
      p:authenticationManager-ref="userAuthentication"
      p:authenticationFailureHandler-ref="customAuthenticationFailureHandler"
      p:authenticationSuccessHandler-ref="customAuthenticationSuccessHandler"
      p:postOnly="false" />

<!-- Custom authentication manager. !!! Username and password must not be the same !!! -->
<bean id="userAuthentication" class="tradeManager.service.authentication.UserAuthentication" />

<!-- default failure URL -->
<bean id="customAuthenticationFailureHandler"
      class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"
      p:defaultFailureUrl="/crimea/auth/login?error=true" />

<!-- default target URL -->
<bean id="customAuthenticationSuccessHandler"
      class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"
      p:defaultTargetUrl="/crimea/main/common" />

<!-- The AuthenticationEntryPoint -->
<bean id="authenticationEntryPoint"
      class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"
      p:loginFormUrl="/crimea/auth/login" />

<!--  Spring Security autowire the parent property  -->
<security:authentication-manager/>

</beans>

我没有显示用户模型因为它标准。 Acess由Integer var:

管理
   /**
     * Access level.
     * 1 = Admin role
     * 2 = Regular role
     */
    @Column(name = "Access", nullable = false)
    private Integer access;

Ок,没有得到任何有用的答案,所以尽我所能。首先,这条线引起了我的注意:

<security:intercept-url pattern="/crimea/main/common" access="hasRole('ROLE_ADMIN','ROLE_USER')"

我把它改为:

<security:intercept-url pattern="/crimea/main/common" access="hasRole('ROLE_USER')"

好的,我做了更多,并将查询更改为用户名,我从以下地址直接访问:

list = userDAO.findAllByParam("from username",auth.getName());

为:

list = getSessionFactory().getCurrentSession().createCriteria(User.class)
                    .add(Restrictions.eq("username", auth.getName())).list();

并将认证会话属性添加到类中并开始工作He =(( 那么,任何人都可以向我解释为什么我的CustomHibernateDaoSupport类不起作用吗?

行。我解决了我的问题))

首先?我更改了@Repository(“employeeDAOImpl”)注释的位置。 我将SQL驱动程序更改为com.jolbox.bonecp.BoneCPDataSource naw我的datasourse配置loks喜欢这个:

<!-- for database, imports the properties from database.properties -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="idleConnectionTestPeriod" value="60"/>
    <property name="idleMaxAge" value="240"/>
    <property name="maxConnectionsPerPartition" value="30"/>
    <property name="minConnectionsPerPartition" value="10"/>
    <property name="partitionCount" value="3"/>
    <property name="acquireIncrement" value="5"/>
    <property name="statementsCacheSize" value="100"/>
    <property name="releaseHelperThreads" value="3"/>
</bean>

将Spring shema改为:

<tx:annotation-driven transaction-manager="transactionManager"/>
<mvc:annotation-driven />
在UserAuthentication类中的

我为NullPointer添加了chek

 if (entity == null) {
        throw new BadCredentialsException("User does not exists!");
    }

添加到pom.xml maven dep。对于新的sql驱动程序:

<dependency>
        <groupId>com.jolbox</groupId>
        <artifactId>bonecp</artifactId>
        <version>0.8.0-rc1</version>
    </dependency>

所以我的身份验证工作正常naw =))

1 个答案:

答案 0 :(得分:2)

我解决了我的问题

  • 首先,我更改了@Repository(“employeeDAOImpl”)注释的位置。
  • 我将SQL驱动程序更改为com.jolbox.bonecp.BoneCPDataSource 现在我的datasourse配置看起来像这样:

    <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
        <property name="driverClass" value="${jdbc.driverClassName}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="idleConnectionTestPeriod" value="60"/>
        <property name="idleMaxAge" value="240"/>
        <property name="maxConnectionsPerPartition" value="30"/>
        <property name="minConnectionsPerPartition" value="10"/>
        <property name="partitionCount" value="3"/>
        <property name="acquireIncrement" value="5"/>
        <property name="statementsCacheSize" value="100"/>
        <property name="releaseHelperThreads" value="3"/>
    </bean>
    
  • 将Spring架构更改为:

    <tx:annotation-driven transaction-manager="transactionManager"/>   <mvc:annotation-driven />

  • UserAuthentication课程中
  • 我添加了null

    的检查

    if(entity == null){     抛出新的BadCredentialsException(“用户不存在!”); }

  • 已添加到pom.xml maven dep。对于新的sql驱动程序:

                com.jolbox             bonecp             0.8.0-RC1         

所以我的身份验证现在工作正常=))