简体   繁体   English

BadCredentialsException是spring-security

[英]BadCredentialsException is spring-security

continue my projects I encountered a problem in the authorization for accounts in Spring setsurity - Problems in the query to the database, all the settings are correct, the database is created at the start of the project, there is no error in debug but at login message pops up in the log: 继续我的项目我在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!

I added few catches to get precise exception and got new NullPointerException 我添加了一些捕获来获得精确的异常并获得新的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)

Can someone explain me what i'm doing wrong? 有人可以解释一下我做错了什么吗? Please help me. 请帮我。

here's the code affected by the query: 这是受查询影响的代码:

@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;
}

here is CustomHibernateDaoSupport: 这是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();
}
}

the security settings are like this: 安全设置如下:

<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>

I'm not showing User model becouse it standart. 我没有显示用户模型因为它标准。 Acess is managed by Integer var: Acess由Integer var管理:

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

Ок, didn't get any helpful answer, so tried my best. Ок,没有得到任何有用的答案,所以尽我所能。 First of all, this line got my attention: 首先,这条线引起了我的注意:

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

I changed it to: 我改成了:

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

OK, I did more and changed query to username and I writed direct access, from: 好的,我做了更多,并将查询更改为用户名,我写了直接访问,来自:

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

to: 至:

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

and added the authentication session attributes to the class and start working He = (( So, can anyone explain to me why my CustomHibernateDaoSupport class does not work?? 并将认证会话属性添加到类中并开始工作He =((那么,任何人都可以向我解释为什么我的CustomHibernateDaoSupport类不起作用?

OK. 好。 I solved my problem )) 我解决了我的问题))

First of all? 首先? I changed location of @Repository("employeeDAOImpl")annotation. 我更改了@Repository(“employeeDAOImpl”)注释的位置。 I changed SQL driver to com.jolbox.bonecp.BoneCPDataSource naw my datasourse config loks likr this: 我将SQL驱动程序更改为com.jolbox.bonecp.BoneCPDataSource naw我的datasourse配置loks likr:

<!-- 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>

changed Spring shema to: 将Spring shema改为:

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

in UserAuthentication class I added chek for NullPointer 在UserAuthentication类中,我为NullPointer添加了chek

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

added to pom.xml maven dep. 添加到pom.xml maven dep。 for new sql driver: 对于新的SQL驱动程序:

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

So My Authentication is working perfect naw =)) 所以我的身份验证工作完美naw =))

I solved my problem 我解决了我的问题

  • First, I changed the location of @Repository("employeeDAOImpl")annotation. 首先,我更改了@Repository(“employeeDAOImpl”)注释的位置。
  • I changed SQL driver to com.jolbox.bonecp.BoneCPDataSource now my datasourse config looks like this: 我将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> 
  • changed Spring schema to: 将Spring架构更改为:

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

  • in UserAuthentication class I added check for a null UserAuthentication类中,我添加了检查null

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

  • added to pom.xml maven dep. 添加到pom.xml maven dep。 for new sql driver: 对于新的SQL驱动程序:

    com.jolbox bonecp 0.8.0-rc1 com.jolbox bonecp 0.8.0-rc1

So my authentication is working perfect now =)) 所以我的身份验证现在工作正常=))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM