スプリングセキュリティを含むJava構成済みのスプリング環境をセットアップしようとしています。アプリケーションはエラーなしで起動しますが、正常にログインできません。
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- 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
実用的な解決策:
ついに私はあなたの助けを借りて実用的な解決策を見つけました。これをありがとう。他の誰かがJava構成された春のセキュリティに興味がある場合は、必要なすべてのファイルをフォローします。
ログイン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">×</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;
}
}