您好,登錄后才能下訂單哦!
這篇文章主要介紹Spring security怎么重寫Filter實現json登錄,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
JSON登錄
上面演示的是一種原始的登錄方案,如果想將用戶名密碼通過JSON的方式進行傳遞,則需要自定義相關過濾器,通過分析源碼我們發現,默認的用戶名密碼提取在UsernamePasswordAuthenticationFilter過濾器中,部分源碼如下:
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username"; public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password"; private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY; private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY; private boolean postOnly = true; public UsernamePasswordAuthenticationFilter() { super(new AntPathRequestMatcher("/login", "POST")); } public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (postOnly && !request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } protected String obtainPassword(HttpServletRequest request) { return request.getParameter(passwordParameter); } protected String obtainUsername(HttpServletRequest request) { return request.getParameter(usernameParameter); } //... //... }
從這里可以看到,默認的用戶名/密碼提取就是通過request中的getParameter來提取的,如果想使用JSON傳遞用戶名密碼,只需要將這個過濾器替換掉即可,自定義過濾器如下:
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE) || request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) { ObjectMapper mapper = new ObjectMapper(); UsernamePasswordAuthenticationToken authRequest = null; try (InputStream is = request.getInputStream()) { Map<String, String> authenticationBean = mapper.readValue(is, Map.class); authRequest = new UsernamePasswordAuthenticationToken(authenticationBean.get("username"), authenticationBean.get("password")); } catch (IOException e) { e.printStackTrace(); authRequest = new UsernamePasswordAuthenticationToken("", ""); } finally { setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } } else { return super.attemptAuthentication(request, response); } } }
這里只是將用戶名/密碼的獲取方案重新修正下,改為了從JSON中獲取用戶名密碼,然后在SecurityConfig中作出如下修改:
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().csrf().disable(); http.addFilterAt(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } @Bean CustomAuthenticationFilter customAuthenticationFilter() throws Exception { CustomAuthenticationFilter filter = new CustomAuthenticationFilter(); filter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException { resp.setContentType("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); RespBean respBean = RespBean.ok("登錄成功!"); out.write(new ObjectMapper().writeValueAsString(respBean)); out.flush(); out.close(); } }); filter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException { resp.setContentype("application/json;charset=utf-8"); PrintWriter out = resp.getWriter(); RespBean respBean = RespBean.error("登錄失敗!"); out.write(new ObjectMapper().writeValueAsString(respBean)); out.flush(); out.close(); } }); filter.setAuthenticationManager(authenticationManagerBean()); return filter; }
搞定~
public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Override @SneakyThrows(IOException.class) //lombok try catch public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (request.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)) { ObjectMapper mapper = new ObjectMapper(); Map<String,String> map = mapper.readValue(request.getInputStream(), Map.class); String username = map.get(super.getUsernameParameter()); String password = map.get(super.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); } return super.attemptAuthentication(request, response); } }
@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.addFilterAt(usernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) } CustomUsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter() throws Exception { CustomUsernamePasswordAuthenticationFilter filter = new CustomUsernamePasswordAuthenticationFilter(); filter.setAuthenticationManager(super.authenticationManagerBean()); filter.setFilterProcessesUrl(customSecurityProperties.getLoginUrl()); //處理登錄成功 filter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler()); //處理登錄失敗 filter.setAuthenticationFailureHandler(new AuthenticationFailureHandler()); return filter; } }
以上是“Spring security怎么重寫Filter實現json登錄”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。