Spring Security登錄接口兼容JSON格式登錄實(shí)現(xiàn)示例
1、概述
前后端分離中,前端和后端的數(shù)據(jù)交互通常是JSON格式,而Spring Security的登錄接口默認(rèn)支持的是form-data或者x-www-form-urlencoded的,如下所示:
那么如何讓Spring Security的登錄接口也支持JSON格式登錄呢?請(qǐng)看下文分析
2、自定義過(guò)濾器
/** * @Author : 一葉浮萍?xì)w大海 * @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); } } /** * 檢查驗(yàn)證碼 * @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 : 一葉浮萍?xì)w大海 * @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()); // 登錄成功回調(diào) usernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(successHandler); // 登錄失敗回調(diào) 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() /** * 注銷登錄回調(diào) */ .logout() .logoutUrl("/logout") .logoutSuccessHandler(logoutSuccessHandler) .permitAll() .and() .csrf() .disable() /** * 未認(rèn)證 & 權(quán)限不足回調(diào) */ .exceptionHandling() .authenticationEntryPoint(authenticationEntryPoint) .accessDeniedHandler(accessDeniedHandler); http.addFilterAfter(usernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } }
4、測(cè)試
到此這篇關(guān)于Spring Security登錄接口兼容JSON格式登錄實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Spring Security登錄接口兼容JSON內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
struts+spring+hibernate三個(gè)框架的整合
這篇文章主要介紹了struts+spring+hibernate三個(gè)框架的整合,需要的朋友可以參考下2017-09-09java基于TCP協(xié)議實(shí)現(xiàn)聊天程序
這篇文章主要為大家詳細(xì)介紹了java基于TCP協(xié)議實(shí)現(xiàn)聊天程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07SpringBoot整合Mybatis使用Druid數(shù)據(jù)庫(kù)連接池
這篇文章主要介紹了SpringBoot整合Mybatis使用Druid數(shù)據(jù)庫(kù)連接池,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03springboot2.3 整合mybatis-plus 高級(jí)功能及用法詳解
這篇文章主要介紹了springboot2.3 整合mybatis-plus 高級(jí)功能,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09IntelliJ IDEA全局內(nèi)容搜索和替換教程圖解
很多朋友在做項(xiàng)目時(shí),會(huì)在整個(gè)項(xiàng)目里活指定文件夾下進(jìn)行全局搜索和替換,下面小編給大家?guī)?lái)了IntelliJ IDEA全局內(nèi)容搜索和替換教程圖解,需要的朋友參考下吧2018-04-04springboot實(shí)現(xiàn)SSE(Server?Sent?Event)的示例代碼
SSE?全稱Server?Sent?Event,直譯一下就是服務(wù)器發(fā)送事件,本文主要為大家詳細(xì)介紹了springboot實(shí)現(xiàn)SSE的相關(guān)知識(shí),需要的可以參考一下2024-04-04Nacos客戶端配置中心緩存動(dòng)態(tài)更新實(shí)現(xiàn)源碼
這篇文章主要為大家介紹了Nacos客戶端配置中心緩存動(dòng)態(tài)更新實(shí)現(xiàn)源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-03-03