使用SpringSecurity中的UserDetailService通过电子邮件登录身份验证

时间:2017-02-16 09:21:12

标签: java hibernate spring-mvc

我尝试使用Spring Security UserDetailService身份验证使用Email而不是UserName登录,但我无法登录并获取

  

org.springframework.security.authentication.InternalAuthenticationServiceException。

当我调试代码时,调试器不会追踪

  

用户user = userDao.findByUserName(useremail);来自UserServiceImpl.java并发生错误。

可能在某个地方需要更多步骤。 配置和Java代码和错误日志如下: -

的applicationContext.xml

<security:http auto-config="true">
        <security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
        <security:intercept-url pattern="/customer/**" access="ROLE_USER" />
        <security:form-login login-page="/login"
            default-target-url="/product/productList/all" authentication-failure-url="/login?error"
            username-parameter="username" password-parameter="password" />
        <security:logout logout-success-url="/login?logout" />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider user-service-ref="userServiceImpl">
                <security:password-encoder ref="bcryptEncoder" />
        </security:authentication-provider>
    </security:authentication-manager>

    <bean id="userServiceImpl" class="com.emusicstore.service.impl.UserServiceImpl" />

    <bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" >
    <constructor-arg name="strength" value="11" />
    </bean>

的Login.jsp

<form name="loginForm" action="<c:url value="/j_spring_security_check" />" method="post">

                <c:if test="${not empty error}">
                    <div class="error" style="color: #ff0000;">${error}</div>
                </c:if>

                <div class="form-group">
                    <label for="username">Email : </label>
                    <input type="text" id="username" name="username" class="form-control" />
                </div>
                <div class="form-group">
                    <label for="password">Passwrod:</label>
                    <input type="password" id="password" name="password" class="form-control" />
                </div>
                <input type="submit" value="Submit" class="btn btn-default">
                <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
            </form>

UserServiceImpl.java

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.jaas.AuthorityGranter;
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.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.emusicstore.dao.UserDao;
import com.emusicstore.model.Users;
import com.emusicstore.service.UserService;
@Service
@Transactional
@Qualifier("userServiceImpl")
public class UserServiceImpl implements UserDetailsService{

    @Autowired
    private UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String useremail)
            throws UsernameNotFoundException {
        Users user = userDao.findByUserEmail(useremail);
        if(user == null){
            throw new UsernameNotFoundException("UserName or Password Invalid.");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.getEnabled(), true, true, true, getGrantedAuthorities(userDao.getUserRole(user.getUsersId())));
    }

    private final List<GrantedAuthority> getGrantedAuthorities(final List<String> roleList) {
        final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (final String role : roleList) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        return authorities;
}
}

控制台错误如下:

  

错误:   org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter    - 尝试验证用户时发生内部错误。 org.springframework.security.authentication.InternalAuthenticationServiceException     在   org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:110)     在   org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:132)     在   org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)     在   org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177)     在   org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:92)     在   org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211)     在   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)     在   org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)     在   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)     在   org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)     在   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     在   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)     在   org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)     在   org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)     在   org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)     在   org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)     在   org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)     在   org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)     在   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)     在   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)     在   org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)     在   org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)     在   org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)     在   org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)     在   org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)     在   org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)     在   org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)     在   org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)     在   org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)     在   org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:674)     在   org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1500)     在   org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.run(NioEndpoint.java:1456)     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)     在   org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)     在java.lang.Thread.run(未知来源)引起:   java.lang.NullPointerException at   com.emusicstore.service.impl.UserServiceImpl.loadUserByUsername(UserServiceImpl.java:33)     在   org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:102)     ......还有35个

请帮助我克服上述错误。

非常感谢。

3 个答案:

答案 0 :(得分:0)

我相信你的自定义代码中有一个简单的 NullPointerException 。将断点放在33位的UserServiceImpl.java中并检查。

  

引起:java.lang.NullPointerException at   com.emusicstore.service.impl.UserServiceImpl.loadUserByUsername(UserServiceImpl.java:33)

答案 1 :(得分:0)

 Users user = userDao.findByUserEmail(useremail);

高于userDao.findByUserEmail(useremail);会返回空值。

答案 2 :(得分:0)

对于我来说,this link有所帮助。这是个抢购的问题。