自定义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
原理待更新。。。
推荐阅读
- Spring|Spring Boot前后端分离之后端开发
- SpringBoot|[SpringBoot系列]SpringBoot如何整合SSMP
- java|基于SpringBoot的SSMP整合案例
- SpringBoot|[SpringBoot系列]基础过渡与夯实(创建Boot项目的新方式、Boot简化核心)
- SpringBoot|[SpringBoot系列]基础过渡与夯实(基础配置)
- 微服务|Eureka快速入门,Eureka简介,什么是Eureka(Eureka注册中心配置)
- mall学习教程|Mall电商实战项目微服务版本全面升级,支持最新版SpringCloud,权限解决方案升级...
- java框架|SpringBoot入门(九)数据访问
- vue|Vue+springboot前后端分离实现简单的注册登录