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、自定義過濾器
/**
* @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-09
java基于TCP協(xié)議實(shí)現(xiàn)聊天程序
這篇文章主要為大家詳細(xì)介紹了java基于TCP協(xié)議實(shí)現(xiàn)聊天程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
SpringBoot整合Mybatis使用Druid數(shù)據(jù)庫連接池
這篇文章主要介紹了SpringBoot整合Mybatis使用Druid數(shù)據(jù)庫連接池,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
springboot2.3 整合mybatis-plus 高級(jí)功能及用法詳解
這篇文章主要介紹了springboot2.3 整合mybatis-plus 高級(jí)功能,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
IntelliJ IDEA全局內(nèi)容搜索和替換教程圖解
很多朋友在做項(xiàng)目時(shí),會(huì)在整個(gè)項(xiàng)目里活指定文件夾下進(jìn)行全局搜索和替換,下面小編給大家?guī)砹薎ntelliJ IDEA全局內(nèi)容搜索和替換教程圖解,需要的朋友參考下吧2018-04-04
springboot實(shí)現(xiàn)SSE(Server?Sent?Event)的示例代碼
SSE?全稱Server?Sent?Event,直譯一下就是服務(wù)器發(fā)送事件,本文主要為大家詳細(xì)介紹了springboot實(shí)現(xiàn)SSE的相關(guān)知識(shí),需要的可以參考一下2024-04-04
Nacos客戶端配置中心緩存動(dòng)態(tài)更新實(shí)現(xiàn)源碼
這篇文章主要為大家介紹了Nacos客戶端配置中心緩存動(dòng)態(tài)更新實(shí)現(xiàn)源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-03-03

