草庐IT

java - Spring 安全 : Java Config does not work

coder 2024-03-11 原文

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

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[] { "/" };
    }
}

安全初始化器

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

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

安全配置

  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";
    }

}

登录.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>

登录 Controller

   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

最佳答案

工作解决方案:

在您的帮助下,我终于找到了可行的解决方案。谢谢你。如果其他人对 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;
    }

}

关于java - Spring 安全 : Java Config does not work,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20068593/

有关java - Spring 安全 : Java Config does not work的更多相关文章

  1. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  2. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  3. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  4. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  5. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  6. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  7. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  8. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  9. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  10. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

随机推荐