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:
(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
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:
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:
/**
* 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??
OK. I solved my problem ))
First of all? I changed location of @Repository("employeeDAOImpl")annotation. I changed SQL driver to com.jolbox.bonecp.BoneCPDataSource naw my datasourse config loks likr this:
<!-- 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:
<tx:annotation-driven transaction-manager="transactionManager"/>
<mvc:annotation-driven />
in UserAuthentication class I added chek for NullPointer
if (entity == null) {
throw new BadCredentialsException("User does not exists!");
}
added to pom.xml maven dep. for new sql driver:
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.8.0-rc1</version>
</dependency>
So My Authentication is working perfect naw =))
I solved my problem
I changed SQL driver to com.jolbox.bonecp.BoneCPDataSource now my datasourse config looks like this:
<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:
<tx:annotation-driven transaction-manager="transactionManager"/>
<mvc:annotation-driven />
in UserAuthentication
class I added check for a null
if (entity == null) { throw new BadCredentialsException("User does not exists!"); }
added to pom.xml
maven dep. for new sql driver:
com.jolbox bonecp 0.8.0-rc1
So my authentication is working perfect now =))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.