Spring Security:Java Config不起作用

时间:2013-11-19 10:08:53

标签: java spring spring-mvc spring-security spring-java-config

我正在尝试建立一个包含spring security的java可配置spring环境。应用程序启动没有任何错误,但我无法成功登录。

WebAppInitializer

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.springframework.core.annotation.Order;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

@Order(value = 1)
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer  {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
    }

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { HibernateConfig.class, SecurityConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { WebAppConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

SecurityInitializer

import org.springframework.core.annotation.Order;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

@Order(value = 2)
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}

SecurityConfig

  import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
            .ignoring()
                .antMatchers("/webjars/**","/css/**","/img/**");
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
          .jdbcAuthentication()
              .dataSource(dataSource)
              .usersByUsernameQuery(getUserQuery())
              .authoritiesByUsernameQuery(getAuthoritiesQuery());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .anyRequest().hasAnyAuthority("EMPLOYEE", "TEAM_LEADER", "ADMIN")
            .and()
        .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/success-login", true)
            .loginProcessingUrl("/process-login")
            .failureUrl("/error-login")
            .permitAll() 
            .and()
        .logout()
            .logoutSuccessUrl("/login")
            .permitAll()
            .and()
        .rememberMe()
            .and()
        .csrf()
            .disable();
    }

    private String getUserQuery() {
        return "SELECT e_mail as username, password as password, active as enabled "
                + "FROM employee "
                + "WHERE e_mail = ?";
    }

    private String getAuthoritiesQuery() {
        return "SELECT DISTINCT employee.e_mail as username, role.name as authority "
                + "FROM employee, employee_role, role "
                + "WHERE employee.id = employee_role.employee_id "
                + "AND role.id = employee_role.role_id "
                + "AND employee.e_mail = ? "
                + "AND employee.active = 1";
    }

}

的login.jsp

    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>


<div class="login-container">
    <form class="form-signin" method="POST" action="<c:url value='/process-login'/>">
        <h2 class="form-signin-heading">Anmelden</h2>
        <c:if test="${error == true}">
            <div class="alert alert-danger">
                <a class="close" data-dismiss="alert" href="#">×</a>
                <p>Login fehlgeschlagen: Eingegebener Nutzername oder Passwort ist falsch.</p>
            </div>
        </c:if>
        <input type="text" name="j_username" id="j_username"
            class="form-control" placeholder="eMail Adresse" required autofocus>
        <input type="password" name="j_password" id="j_password"
            class="form-control" placeholder="Passwort" required> <label
            class="checkbox"> <input type="checkbox" value="remember-me">
            Angemeldet bleiben
        </label>
        <button class="btn btn-lg btn-primary btn-block" type="submit">Anmelden</button>
    </form>
</div>

的LoginController

   import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LoginController {

    @RequestMapping(value={"/login"}, method=RequestMethod.GET)
    public ModelAndView showLoginPage() {
        return new ModelAndView("login/login");
    }

    @RequestMapping(value="/success-login", method=RequestMethod.POST)  
    public ModelAndView successLogin() {  
        return new ModelAndView("/dashboard");  
    } 

    @RequestMapping(value="/process-login", method=RequestMethod.POST)  
    public ModelAndView processLogin() {  
        return new ModelAndView("/dashboard");  
    } 

    @RequestMapping(value="/error-login", method=RequestMethod.GET)  
    public ModelAndView invalidLogin() {  
        ModelAndView modelAndView = new ModelAndView("login/login");  
        modelAndView.addObject("error", true);  
        return modelAndView;  
    }  

    @RequestMapping(value="/logout", method=RequestMethod.POST)  
    public ModelAndView logout() {  
        return new ModelAndView("login/login");
    }  
}

数据库: 角色表的内容:“EMPLOYEE”,“TEAM_LEADER”,“ADMIN”,

我正在寻找解决方案很长一段时间,但不幸的是我找不到错误。我很感谢你的所有建议。

更新1 - 一次登录后Log4J日志

2013-11-19 11:17:47,223 [DEBUG] [AbstractSecurityInterceptor.java : 310] org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9056f12c: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@380f4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 45D43FE758F35164E5FE7BC9D08F81B8; Granted Authorities: ROLE_ANONYMOUS
2013-11-19 11:17:47,231 [DEBUG] [AffirmativeBased.java : 65] org.springframework.security.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@2f7b1445, returned: -1
2013-11-19 11:17:47,237 [DEBUG] [ExceptionTranslationFilter.java : 165] org.springframework.security.web.access.ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Zugriff verweigert
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:139)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
2013-11-19 11:17:47,239 [DEBUG] [AndRequestMatcher.java : 66] org.springframework.security.web.util.matcher.AndRequestMatcher - Trying to match using Ant [pattern='/**', GET]
2013-11-19 11:17:47,239 [DEBUG] [AntPathRequestMatcher.java : 127] org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'POST /j_spring_security_check' doesn't match 'GET /**
2013-11-19 11:17:47,240 [DEBUG] [AndRequestMatcher.java : 69] org.springframework.security.web.util.matcher.AndRequestMatcher - Did not match
2013-11-19 11:17:47,240 [DEBUG] [HttpSessionRequestCache.java : 44] org.springframework.security.web.savedrequest.HttpSessionRequestCache - Request not saved as configured RequestMatcher did not match
2013-11-19 11:17:47,240 [DEBUG] [ExceptionTranslationFilter.java : 185] org.springframework.security.web.access.ExceptionTranslationFilter - Calling Authentication entry point.
2013-11-19 11:17:47,241 [DEBUG] [DefaultRedirectStrategy.java : 36] org.springframework.security.web.DefaultRedirectStrategy - Redirecting to 'http://localhost:8080/holidayplanner/login'
2013-11-19 11:17:47,241 [DEBUG] [HttpSessionSecurityContextRepository.java : 300] org.springframework.security.web.context.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2013-11-19 11:17:47,242 [DEBUG] [SecurityContextPersistenceFilter.java : 97] org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
2013-11-19 11:17:47,246 [DEBUG] [AntPathRequestMatcher.java : 145] org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/login'; against '/webjars/**'
2013-11-19 11:17:47,246 [DEBUG] [AntPathRequestMatcher.java : 145] org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/login'; against '/css/**'
2013-11-19 11:17:47,246 [DEBUG] [AntPathRequestMatcher.java : 145] org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/login'; against '/img/**'
2013-11-19 11:17:47,247 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2013-11-19 11:17:47,247 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2013-11-19 11:17:47,247 [DEBUG] [HttpSessionSecurityContextRepository.java : 148] org.springframework.security.web.context.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
2013-11-19 11:17:47,247 [DEBUG] [HttpSessionSecurityContextRepository.java : 90] org.springframework.security.web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@2664e105. A new one will be created.
2013-11-19 11:17:47,247 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2013-11-19 11:17:47,247 [DEBUG] [HstsHeaderWriter.java : 129] org.springframework.security.web.header.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2f389f24
2013-11-19 11:17:47,247 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2013-11-19 11:17:47,247 [DEBUG] [AntPathRequestMatcher.java : 145] org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/login'; against '/logout'
2013-11-19 11:17:47,248 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 5 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2013-11-19 11:17:47,248 [DEBUG] [AntPathRequestMatcher.java : 127] org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request 'GET /login' doesn't match 'POST /success-login
2013-11-19 11:17:47,248 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 6 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2013-11-19 11:17:47,248 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 7 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2013-11-19 11:17:47,248 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 8 of 12 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter'
2013-11-19 11:17:47,248 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2013-11-19 11:17:47,248 [DEBUG] [AnonymousAuthenticationFilter.java : 102] org.springframework.security.web.authentication.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9056f12c: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@380f4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 45D43FE758F35164E5FE7BC9D08F81B8; Granted Authorities: ROLE_ANONYMOUS'
2013-11-19 11:17:47,249 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2013-11-19 11:17:47,249 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2013-11-19 11:17:47,249 [DEBUG] [FilterChainProxy.java : 337] org.springframework.security.web.FilterChainProxy - /login at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2013-11-19 11:17:47,249 [DEBUG] [AbstractSecurityInterceptor.java : 194] org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /login; Attributes: [permitAll]
2013-11-19 11:17:47,249 [DEBUG] [AbstractSecurityInterceptor.java : 310] org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9056f12c: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@380f4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 45D43FE758F35164E5FE7BC9D08F81B8; Granted Authorities: ROLE_ANONYMOUS
2013-11-19 11:17:47,249 [DEBUG] [AffirmativeBased.java : 65] org.springframework.security.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@2f7b1445, returned: 1
2013-11-19 11:17:47,249 [DEBUG] [AbstractSecurityInterceptor.java : 215] org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Authorization successful
2013-11-19 11:17:47,250 [DEBUG] [AbstractSecurityInterceptor.java : 227] org.springframework.security.web.access.intercept.FilterSecurityInterceptor - RunAsManager did not change Authentication object
2013-11-19 11:17:47,250 [DEBUG] [FilterChainProxy.java : 323] org.springframework.security.web.FilterChainProxy - /login reached end of additional filter chain; proceeding with original chain
2013-11-19 11:17:47,254 [DEBUG] [ExceptionTranslationFilter.java : 115] org.springframework.security.web.access.ExceptionTranslationFilter - Chain processed normally
2013-11-19 11:17:47,254 [DEBUG] [HttpSessionSecurityContextRepository.java : 300] org.springframework.security.web.context.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2013-11-19 11:17:47,254 [DEBUG] [SecurityContextPersistenceFilter.java : 97] org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed

1 个答案:

答案 0 :(得分:10)

工作解决方案:

最后,我在你的帮助下找到了一个可行的解决方案。谢谢你。如果其他人对java配置的spring security感兴趣,请关注所有需要的文件:

登录JSP:

<div class="login-container">
<form class="form-signin navbar navbar-default" method="POST" action="<c:url value='/login/process-login'/>">
    <div class="form-signin-img">
        <span class="form-signin-img-helper"></span>
        <img src="<c:url value='/img/itensis_logo.gif'/>" />
    </div>
    <h2 class="form-signin-heading">${msg_heading}</h2>
    <c:if test="${error == true}">
        <div class="alert alert-danger">
            <button type="button" class="close close-box">&times;</button>
            <p>${msg_error}</p>
        </div>
    </c:if>
    <input type="text" name="security_username" id="security_username" class="form-control" placeholder="${msg_username}" required autofocus>
    <input type="password" name="security_password" id="security_password" class="form-control" placeholder="${msg_password}" required>

    <label class="checkbox"> 
        <input type="checkbox" name="remember_me_checkbox"> ${msg_rememberMe}
    </label> 
    <button class="btn btn-lg btn-primary btn-block" type="submit">
        <i class="fa fa-sign-in fa-lg"></i>
        <span>${msg_login}</span>
    </button>
</form>

<强> SecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled=true, prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired private UserDetailsService userDetailService;
    @Autowired private DataSource dataSource;

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
            .ignoring()
                .antMatchers("/js/**","/css/**","/img/**","/webjars/**","/pages/**");
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        ShaPasswordEncoder shaPasswordEncoder = new ShaPasswordEncoder(256);
        auth
          .jdbcAuthentication()
              .dataSource(dataSource)
              .usersByUsernameQuery(getUserQuery())
              .authoritiesByUsernameQuery(getAuthoritiesQuery())
              .passwordEncoder(shaPasswordEncoder);
    }

    @Bean 
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
         return super.authenticationManagerBean();
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
            .anyRequest().hasAuthority("BASIC_PERMISSION")
            .and()
        .formLogin()
            .loginPage("/login/login")
            .defaultSuccessUrl("/login/success-login", true)
            .failureUrl("/login/error-login")
            .loginProcessingUrl("/login/process-login")
            .usernameParameter("security_username")
            .passwordParameter("security_password")
            .permitAll() 
            .and()
        .logout()
            .logoutSuccessUrl("/login/login")
            .logoutUrl("/login/logout")
            .permitAll()
            .and()
        .rememberMe()
            .key("your_key")
            .rememberMeServices(rememberMeServices())
            .and()
        .csrf()
            .disable();
    }

    @Bean
    public RememberMeServices rememberMeServices() {
        // Key must be equal to rememberMe().key() 
        TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("your_key", userDetailService);
        rememberMeServices.setCookieName("remember_me_cookie");
        rememberMeServices.setParameter("remember_me_checkbox");
        rememberMeServices.setTokenValiditySeconds(2678400); // 1month
        return rememberMeServices;
    }

    @Bean
    public UserDetailsService userDetailService() {
        return new SecurityUserDetailService();
    }

    private String getUserQuery() {
        return "SELECT username as username, password as password, active as enabled "
                + "FROM employee "
                + "WHERE username = ?";
    }

    private String getAuthoritiesQuery() {
        return "SELECT DISTINCT employee.username as username, permission.name as authority "
                + "FROM employee, employee_role, role, role_permission, permission "
                + "WHERE employee.id = employee_role.employee_id "
                + "AND role.id = employee_role.role_id "
                + "AND role.id = role_permission.role_id "
                + "AND permission.id = role_permission.permission_id "
                + "AND employee.username = ? "
                + "AND employee.active = 1";
    }
}

<强> LoginController.java

@Controller
@RequestMapping("/login")
public class LoginController {

    @RequestMapping(value={"/login"}, method=RequestMethod.GET)
    public ModelAndView showLoginPage() {
        return new ModelAndView("loginForm");
    }

    @RequestMapping(value="/success-login", method=RequestMethod.GET)  
    public String successLogin() {  
        return "forward:/dashboard/dashboard";
    } 

    @RequestMapping(value="/error-login", method=RequestMethod.GET)  
    public ModelAndView invalidLogin() {  
        ModelAndView modelAndView = new ModelAndView("loginForm");  
        modelAndView.addObject("error", true);  
        return modelAndView;  
    }  

    @RequestMapping(value="/logout", method=RequestMethod.POST)  
    public ModelAndView logout() {  
        return new ModelAndView("dashboardForm");
    }  
}

更新1:SecurityUserDetailService

@Service
@Transactional
public class SecurityUserDetailService implements UserDetailsService {

    @Autowired private EmployeeService employeeService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {
            Employee loggedInEmployee = employeeService.findEmployeeByUsername(username);
            List<GrantedAuthority> authorities = getAuthorities(loggedInEmployee);
            boolean enabled = true;
            boolean accountNonExpired = true;
            boolean credentialsNonExpired = true;
            boolean accountNonLocked = true;
            return new User(
                    loggedInEmployee.getUsername(),
                    loggedInEmployee.getPassword().toLowerCase(),
                    enabled,
                    accountNonExpired,
                    credentialsNonExpired,
                    accountNonLocked,
                    authorities);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static List<GrantedAuthority> getAuthorities(Employee employee) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (Role role : employee.getRoles()) {
            for (Permission permission : role.getPermissions()) {
                authorities.add(new SimpleGrantedAuthority(permission.getName()));
            }
        }
        return authorities;
    }

}