使用MyBatis作为ORM的Spring Security身份验证不起作用

时间:2015-10-08 11:17:11

标签: spring-security mybatis spring-mybatis

我使用spring security 4和mybatis作为数据库的orm。对于身份验证,我使用移动号码和生成的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

1 个答案:

答案 0 :(得分:1)

我犯了一个愚蠢的错误。我需要在类中添加UserDetailsS​​ervicesImpl对象并自动装配它,而不是在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");
}