Spring|Spring Security前后端分离实现

自定义UsernamePasswordAuthenticationFilter

package com.monkeylessey.xp; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Map; /** * @author xp * @version 1.0 * @date 2022/3/31 0031 17:13 */ public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {@Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { // post请求 if (!request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); }if (request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) { try { Map map = new ObjectMapper().readValue(request.getInputStream(), Map.class); String username = (String) map.get(getUsernameParameter()); String password = (String) map.get(getPasswordParameter()); username = (username != null) ? username : ""; username = username.trim(); password = (password != null) ? password : ""; UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); // Allow subclasses to set the "details" property setDetails(request, token); return this.getAuthenticationManager().authenticate(token); } catch (IOException e) { e.printStackTrace(); } } return super.attemptAuthentication(request,response); } }

Security配置类:
package com.monkeylessey.xp.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.monkeylessey.xp.MyUsernamePasswordAuthenticationFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * @author xp * @version 1.0 * @date 2022/3/31 0031 17:52 */ @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter {@Bean public UserDetailsService getUserDetails() { InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager(); inMemoryUserDetailsManager.createUser(User.withUsername("xp").password("{noop}666").roles("admin").build()); return inMemoryUserDetailsManager; }@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(getUserDetails()); }@Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); }/** * 自定义认证过滤器 * @return * @throws Exception */ @Bean public MyUsernamePasswordAuthenticationFilter get() throws Exception { MyUsernamePasswordAuthenticationFilter myLoginFilter = new MyUsernamePasswordAuthenticationFilter(); myLoginFilter.setUsernameParameter("u"); myLoginFilter.setPasswordParameter("p"); myLoginFilter.setFilterProcessesUrl("/xplogin"); // 指定认证的请求 myLoginFilter.setAuthenticationManager(authenticationManagerBean()); myLoginFilter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { Map map = new HashMap<>(); map.put("msg", "登录成功"); String s = new ObjectMapper().writeValueAsString(map); response.getWriter().print(s); response.setContentType("application/json; charset=UTF-8"); response.setStatus(HttpStatus.OK.value()); System.out.println("认证失败"); } }); myLoginFilter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { Map map = new HashMap<>(); map.put("msg", "登录失败"); String s = new ObjectMapper().writeValueAsString(map); response.getWriter().print(s); response.setContentType("application/json; charset=UTF-8"); response.setStatus(HttpStatus.FORBIDDEN.value()); System.out.println("认证失败"); } }); return myLoginFilter; }@Override protected void configure(HttpSecurity http) throws Exception { http.formLogin(); http.authorizeRequests() .anyRequest().authenticated(); http.csrf().disable(); // at是用filter去替换某个filter http.addFilterAt(get(), UsernamePasswordAuthenticationFilter.class); } }

测试接口
package com.monkeylessey.xp.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author xp * @version 1.0 * @date 2022/3/31 0031 15:06 */ @RestController @RequestMapping public class TestController {@GetMapping("/one") public String testA() { return "小老弟你来啦"; } }

随手一个依赖吧
org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-web

原理待更新。。。

    推荐阅读