spring security 最简单的登录莫过于form表单登录,但是要做到极致的交互式体验,还是需要用到ajax登录
首先我们借助于(五)Spring Security基于数据库的权限授权的登录页面
在WebSecurityConfig 里配置
@Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/login","/login_page","/home","/getCode").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login_page") /* 未登录的自动跳转到这个接口 */ .loginProcessingUrl("/login") /* 指定登录逻辑路径 ,由过滤器拦截*/ .successHandler(successHandler) .failureHandler(failureHandler) .and() .logout() .logoutSuccessUrl("/home"); http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);由于配置的loginPage("/login_page")跳转的页面是json数据,不是一个页面,所以问哦们需要自定义一个AuthenticationEntryPoint,
AuthenticationEntryPoint的实现类有多种 AuthenticationEntryPoint在ExceptionTranslationFilter使用, ExceptionTranslationFilter会截获AuthenticationException 或者AccessDeniedException异常,AuthenticationEntryPoint. Commence(…)就会被调用。 如下:源代码public class ExceptionTranslationFilter extends GenericFilterBean { private AuthenticationEntryPoint authenticationEntryPoint; ...... public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; try { chain.doFilter(request, response); this.logger.debug("Chain processed normally"); } catch (IOException var9) { throw var9; } catch (Exception var10) { ...... this.handleSpringSecurityException(request, response, chain, (RuntimeException)ase); } } private void handleSpringSecurityException(HttpServletRequest request, HttpServletResponse response, FilterChain chain, RuntimeException exception) throws IOException, ServletException { ...... this.sendStartAuthentication(request, response, chain, (AuthenticationException)exception); ...... } protected void sendStartAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, AuthenticationException reason) throws ServletException, IOException { SecurityContextHolder.getContext().setAuthentication((Authentication)null); this.requestCache.saveRequest(request, response); this.logger.debug("Calling Authentication entry point."); /* 调用 */ this.authenticationEntryPoint.commence(request, response, reason); } ...... 当用户访问受限的资源时跳转登录页面@Component public class UnauthorizedEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { if(isAjaxRequest(request)){ response.sendError(HttpServletResponse.SC_UNAUTHORIZED,authException.getMessage()); }else{ response.sendRedirect("/login"); } } private boolean isAjaxRequest(HttpServletRequest request) { return request.getHeader("X-Requested-With") != null&&request.getHeader("X-Requested-With").equals("XMLHttpRequest"); } }Spring Security基于ajax登录