Spring Security登录接口兼容JSON格式登录实现示例
作者:YYAugenstern
前后端分离中,前端和后端的数据交互通常是JSON格式,本文主要介绍了Spring Security登录接口兼容JSON格式登录实现示例,具有一定的参考价值,感兴趣的可以了解一下
1、概述
前后端分离中,前端和后端的数据交互通常是JSON格式,而Spring Security的登录接口默认支持的是form-data或者x-www-form-urlencoded的,如下所示:
那么如何让Spring Security的登录接口也支持JSON格式登录呢?请看下文分析
2、自定义过滤器
/** * @Author : 一叶浮萍归大海 * @Date: 2024/1/13 9:30 * @Description: */ public class MyUsernamePasswordAuthenticationFilter7007 extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (!HttpMethod.POST.name().equals(request.getMethod())) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } String sessionCode = (String) request.getSession().getAttribute("code"); if (MediaType.APPLICATION_JSON_VALUE.equals(request.getContentType()) || MediaType.APPLICATION_JSON_UTF8_VALUE.equals(request.getContentType())) { Map<String, String> loginData = new HashMap<>(16); try { loginData = new ObjectMapper().readValue(request.getInputStream(), Map.class); } catch (Exception e) { e.printStackTrace(); } finally { String paramCode = loginData.get("code"); try { checkCode(response,paramCode,sessionCode); } catch (Exception e) { throw new RuntimeException(e); } } String username = loginData.get(getUsernameParameter()); String password = loginData.get(getPasswordParameter()); if (username == null) { username = ""; } if (password == null) { password = ""; } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); setDetails(request,authRequest); return this.getAuthenticationManager().authenticate(authRequest); } else { try { checkCode(response,request.getParameter("code"),sessionCode); } catch (Exception e) { throw new RuntimeException(e); } return super.attemptAuthentication(request, response); } } /** * 检查验证码 * @param response * @param paramCode * @param sessionCode */ private void checkCode(HttpServletResponse response, String paramCode, String sessionCode) throws Exception { if (StringUtils.isBlank(paramCode)) { R r = R.error(ResponseEnum.VERIFY_CODE_IS_NULL.getCode(), ResponseEnum.VERIFY_CODE_IS_NULL.getMessage()); response.setContentType("application/json;charset=utf-8"); PrintWriter out = response.getWriter(); out.write(new ObjectMapper().writeValueAsString(r)); out.flush(); out.close(); return; } if (StringUtils.isBlank(sessionCode)) { R r = R.error(ResponseEnum.VERIFY_CODE_IS_EXPIRED.getCode(), ResponseEnum.VERIFY_CODE_IS_EXPIRED.getMessage()); response.setContentType("application/json;charset=utf-8"); PrintWriter out = response.getWriter(); out.write(new ObjectMapper().writeValueAsString(r)); out.flush(); out.close(); return; } if (!StringUtils.equals(paramCode.toLowerCase(), sessionCode.toLowerCase())) { R r = R.error(ResponseEnum.VERIFY_CODE_IS_NOT_MATCH.getCode(), ResponseEnum.VERIFY_CODE_IS_NOT_MATCH.getMessage()); response.setContentType("application/json;charset=utf-8"); PrintWriter out = response.getWriter(); out.write(new ObjectMapper().writeValueAsString(r)); out.flush(); out.close(); return; } } }
3、配置类
/** * @Author : 一叶浮萍归大海 * @Date: 2024/1/11 21:50 * @Description: Spring Security配置类 */ @Configuration public class MyWebSecurityConfigurerAdapter7007 extends WebSecurityConfigurerAdapter { @Resource private MyAuthenticationSuccessHandler7007 successHandler; @Resource private MyAuthenticationFailureHandler7007 failureHandler; @Resource private MyLogoutSuccessHandler7007 logoutSuccessHandler; @Resource private MyAuthenticationEntryPoint7007 authenticationEntryPoint; @Resource private MyAccessDeniedHandler7007 accessDeniedHandler; @Resource private UserDetailsService userDetailsServiceImpl; /** * 密码加密器 * * @return */ @Bean PasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); } /** * 定义基于MyBatis-Plus的用户 * * @return */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsServiceImpl); } /** * 角色继承 * * @return */ @Bean protected RoleHierarchy roleHierarchy() { RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl(); roleHierarchy.setHierarchy("ROLE_admin > ROLE_dba"); return roleHierarchy; } @Bean public MyUsernamePasswordAuthenticationFilter7007 usernamePasswordAuthenticationFilter() throws Exception { MyUsernamePasswordAuthenticationFilter7007 usernamePasswordAuthenticationFilter = new MyUsernamePasswordAuthenticationFilter7007(); usernamePasswordAuthenticationFilter.setFilterProcessesUrl("/login"); usernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManager()); // 登录成功回调 usernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(successHandler); // 登录失败回调 usernamePasswordAuthenticationFilter.setAuthenticationFailureHandler(failureHandler); return usernamePasswordAuthenticationFilter; } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/dba/**").hasRole("dba") .antMatchers("/admin/**").hasRole("admin") .antMatchers("/helloWorld", "/verifyCode/getVerifyCode") .permitAll() .anyRequest() .authenticated() .and() /** * 注销登录回调 */ .logout() .logoutUrl("/logout") .logoutSuccessHandler(logoutSuccessHandler) .permitAll() .and() .csrf() .disable() /** * 未认证 & 权限不足回调 */ .exceptionHandling() .authenticationEntryPoint(authenticationEntryPoint) .accessDeniedHandler(accessDeniedHandler); http.addFilterAfter(usernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } }
4、测试
到此这篇关于Spring Security登录接口兼容JSON格式登录实现示例的文章就介绍到这了,更多相关Spring Security登录接口兼容JSON内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!