0

继续我的项目我在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 我的数据源配置 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 部门。对于新的 sql 驱动程序:

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

所以我的身份验证工作完美无 =))

4

1 回答 1

2

我解决了我的问题

  • 首先,我更改了@Repository("employeeDAOImpl") 注解的位置。
  • 我将 SQL 驱动程序更改为 com.jolbox.bonecp.BoneCPDataSource 现在我的数据源配置如下所示:

    <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) { throw new BadCredentialsException("用户不存在!"); }

  • 添加到pom.xmlMaven 部门。对于新的 sql 驱动程序:

    com.jolbox bonecp 0.8.0-rc1

所以我的身份验证现在很完美=))

于 2013-05-04T16:12:54.710 回答