Spring Security Authentication с MyBatis, поскольку ORM не работает

Я использую spring security 4 и mybatis в качестве формы для базы данных. Для аутентификации я использую номер мобильного телефона и сгенерированный OTP (еще осталось реализовать). Я получаю ошибку нулевого указателя, поскольку класс AuthenticationProvider по какой-то причине не может взаимодействовать с базой данных через ORM. Мой класс конфигурации безопасности

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
    UserDetailsServiceImpl userDetailsService = new UserDetailsServiceImpl();
    auth.userDetailsService(userDetailsService);
    //auth.inMemoryAuthentication().withUser("9822012345").password("password");
}

@Override
public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .antMatchers("/login*").permitAll()
        .antMatchers("/**").access("hasRole('USER')")
        .and().formLogin()
        .and().csrf();
}

Мой интерфейс для пользовательского класса

public interface UserDao {

@Select("SELECT * FROM \"Users\" WHERE \"Email\" = '${Email}'")
@Results(value = {
        @Result(property = "Email", column = "Email"),
        @Result(property = "Name", column = "Name"),
        @Result(property = "MobileNumber", column = "MobileNumber"),
        @Result(property = "LoggedIn", column = "LoggedIn"),
        @Result(property = "Balance", column = "Balance")
       })
public User getUserByEmail(@Param("Email") String Email);

@Select("SELECT * FROM \"Users\" WHERE \"Name\" = '${Name}'")
@Results(value = {
        @Result(property = "Email", column = "Email"),
        @Result(property = "Name", column = "Name"),
        @Result(property = "MobileNumber", column = "MobileNumber"),
        @Result(property = "LoggedIn", column = "LoggedIn"),
        @Result(property = "Balance", column = "Balance")
       })
public User getUserByName(@Param("Name") String Name);

@Select("SELECT * FROM \"Users\" WHERE \"MobileNumber\" = '${MobileNumber}'")
@Results(value = {
        @Result(property = "Email", column = "Email"),
        @Result(property = "Name", column = "Name"),
        @Result(property = "MobileNumber", column = "MobileNumber"),
        @Result(property = "LoggedIn", column = "LoggedIn"),
        @Result(property = "Balance", column = "Balance")
       })
public User getUserByMobileNumber(@Param("MobileNumber") String mobileNumber);  
}

Мой класс, который реализует интерфейс

@Service
@Transactional
public class UserDaoImpl {
private UserDao userDao;

@Autowired
public void setUserDao(UserDao userDao) {
    if(userDao != null) this.userDao = userDao;
}

public User getUserByEmail(String email) {
    return userDao.getUserByEmail(email);
}

public User getUserByName(String email) {
    return userDao.getUserByName(email);
}

public User getUserByMobileNumber(String mobileNumber) {
    System.out.println("Comes in userdaoimpl.. " + mobileNumber);
    User u =  userDao.getUserByMobileNumber(mobileNumber);

    if(u!=null) { return u; }
    else {
        System.out.println("User returned null. Maybe Database problem.");
        return null;
        }
}
}

И моя реализация службы сведений о пользователе

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.iz.zpservice.dao.impl.UserDaoImpl;
import com.iz.zpservice.model.User;

@Service
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService {

@Autowired
UserDaoImpl userDaoImpl = new UserDaoImpl();

public User getUserByMobileNumber(String mobileNumber) {
    return userDaoImpl.getUserByMobileNumber(mobileNumber);
}

@Override
public UserDetails loadUserByUsername(String mobileNumber) throws UsernameNotFoundException {
    System.out.println(mobileNumber + "The number provided.");
    String otp = "password"; /* Add Otp method and 
                              * initialize this 
                              * object
                              */

    try {
        User user = getUserByMobileNumber(mobileNumber);
        System.out.println(user.getName() + "User has been fetched.");
    } catch (UsernameNotFoundException u) {
        throw new UsernameNotFoundException("No such number registered: " + mobileNumber);
    }

    boolean accountNonExpired = true;
    boolean credentialsNonExpired = true;
    boolean accountNonLocked = true;

    return new org.springframework.security.core.userdetails.User(mobileNumber, otp,
            true, accountNonExpired, credentialsNonExpired, accountNonLocked, getAuthorities(mobileNumber));
}

public Collection<? extends GrantedAuthority> getAuthorities(String mobileNumber) {
    List<GrantedAuthority> authList = null;
    authList = new ArrayList<GrantedAuthority>();
    SimpleGrantedAuthority sGA = new SimpleGrantedAuthority(new String("ROLE_USER"));
    authList.add(sGA);
    return authList;
}
}

И трассировка стека

    INFO: Server startup in 6346 ms
9822012345The number provided.
Comes in userdaoimpl.. 9822012345
Oct 08, 2015 4:44:53 PM org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter doFilter
SEVERE: An internal error occurred while trying to authenticate the user.
org.springframework.security.authentication.InternalAuthenticationServiceException
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:125)
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:143)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:167)
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
    at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:93)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:217)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:120)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at com.iz.zpservice.dao.impl.UserDaoImpl.getUserByMobileNumber(UserDaoImpl.java:30)
    at com.iz.zpservice.service.UserDetailsServiceImpl.getUserByMobileNumber(UserDetailsServiceImpl.java:26)
    at com.iz.zpservice.service.UserDetailsServiceImpl.loadUserByUsername(UserDetailsServiceImpl.java:38)
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:114)
    ... 41 more

person JavaGuy    schedule 08.10.2015    source источник


Ответы (1)


Я совершил глупую ошибку. Мне нужно было добавить объект UserDetailsServicesImpl внутри класса и выполнить автоподключение, вместо этого я объявил его внутри метода configure...

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
UserDetailsServiceImpl userDetailsService = new UserDetailsServiceImpl();

@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService);
    //auth.inMemoryAuthentication().withUser("9822012345").password("password");
}
person JavaGuy    schedule 08.10.2015