(七)Spring Security基于ajax登录
目录
- 一:修改form 表单
- 二:创建一个登录接口
- 三:自定义认证入口点(AuthenticationEntryPoint)
- 四:最终配置
- 五:项目地址
spring security 最简单的登录莫过于form表单登录,但是要做到极致的交互式体验,还是需要用到ajax登录
首先我们借助于(五)Spring Security基于数据库的权限授权的登录页面
一:修改form 表单
- 原表单:
<form th:action="@{/login}" method="post"><div><label> User Name : <input type="text" name="username"/> </label></div><div><label> Password: <input type="password" name="password"/> </label></div><div><label> code: <input type="text" name="captcha"/> </label> <img src="/getCode" id="code" alt="验证码" onclick="refresh(this)"/></div><label> <input type="hidden" name="uuid" id="uuid"/> </label><div><input type="submit" value="Sign In"/></div> </form> - 修改后
<form ><div><label> User Name : <input type="text" name="username"/> </label></div><div><label> Password: <input type="password" name="password"/> </label></div><div><label> code: <input type="text" name="captcha"/> </label> <img src="/getCode" id="code" alt="验证码" onclick="refresh(this)"/></div><label> <input type="hidden" name="uuid" id="uuid"/> </label><div><a href="javascript:login();" >登录</a></div> </form> *********************************************************let login=()=>{let username = $("input[name = 'username']");let password = $("input[name = 'password']");let captcha = $("input[name = 'captcha']");let uuid = $("input[name = 'uuid']");$.ajax({type : "POST",url : "/login",data : {"username" : username.val(),"password" : password.val(),"captcha" : captcha.val(),"uuid" : uuid.val()},success: function(result){if(result.code === 1){window.location.href="/";}else {alert('登录失败');}},error : function(data) {alert("错误的用户或密码");},beforeSend : function() {if (username.val() === "") {alert("请输入用户名!");username.focus();return false;}if (password.val() === "") {alert("请输入密码!");password.focus();return false;}}}); };
二:创建一个登录接口
/*** 这个接口用来代替spring security的登录界面*/@GetMapping("/login_page")@ResponseBodypublic Object loginPage() {return new BaseResult(ReturnCode.FAILED.getCode(), "尚未登录,请登录!");}
在WebSecurityConfig 里配置
@Overrideprotected 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);
三:自定义认证入口点(AuthenticationEntryPoint)
由于配置的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 {@Overridepublic 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");} }
四:最终配置
- 关闭crsf
@Overrideprotected 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.csrf().disable(); /* 关闭csrf,否则会拦截ajax请求 */ kuhttp.exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint); /* 用来解决匿名用户访问无权限资源时的异常 */http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);} - 开启crsf
crsf开启,会拦截ajax请求所以需要在请求中加入crsf参数

注意:需要在头部加入这些,否则无法创建session
示例

五:项目地址
Spring Security基于ajax登录
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
