13 changed files with 275 additions and 44 deletions
-
2pom.xml
-
1src/main/java/com/example/demo/DemoApplication.java
-
5src/main/java/com/example/demo/Util/JWTUtil.java
-
27src/main/java/com/example/demo/Util/ReplaceStreamFilter.java
-
123src/main/java/com/example/demo/Util/RequestWrapper.java
-
18src/main/java/com/example/demo/Util/TokenPayload.java
-
6src/main/java/com/example/demo/controller/AdminController.java
-
2src/main/java/com/example/demo/domain/entity/Admin.java
-
10src/main/java/com/example/demo/mapper/AdminMapper.java
-
7src/main/java/com/example/demo/security/SecurityConfig.java
-
108src/main/java/com/example/demo/security/TokenFilter.java
-
8src/main/java/com/example/demo/serviceImpl/AdminServiceImpl.java
-
2src/main/java/com/example/demo/sevice/AdminService.java
@ -0,0 +1,27 @@ |
|||
package com.example.demo.Util; |
|||
|
|||
import jakarta.servlet.*; |
|||
import jakarta.servlet.http.HttpServletRequest; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.io.IOException; |
|||
|
|||
//替换HttpServletRequest |
|||
@Slf4j |
|||
public class ReplaceStreamFilter implements Filter { |
|||
@Override |
|||
public void init(FilterConfig filterConfig) throws ServletException { |
|||
log.info("StreamFilter初始化..."); |
|||
} |
|||
|
|||
@Override |
|||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
|||
ServletRequest requestWrapper = new RequestWrapper((HttpServletRequest) request); |
|||
chain.doFilter(requestWrapper, response); |
|||
} |
|||
|
|||
@Override |
|||
public void destroy() { |
|||
log.info("StreamFilter销毁..."); |
|||
} |
|||
} |
@ -0,0 +1,123 @@ |
|||
package com.example.demo.Util; |
|||
|
|||
import jakarta.servlet.ReadListener; |
|||
import jakarta.servlet.ServletInputStream; |
|||
import jakarta.servlet.ServletRequest; |
|||
import jakarta.servlet.http.HttpServletRequest; |
|||
import jakarta.servlet.http.HttpServletRequestWrapper; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
|
|||
import java.io.*; |
|||
import java.nio.charset.Charset; |
|||
|
|||
|
|||
//包装HttpServletRequest,目的是让其输入流可重复读 |
|||
@Slf4j |
|||
public class RequestWrapper extends HttpServletRequestWrapper { |
|||
/** |
|||
* 存储body数据的容器 |
|||
*/ |
|||
private final byte[] body; |
|||
|
|||
public RequestWrapper(HttpServletRequest request) throws IOException { |
|||
super(request); |
|||
|
|||
// 将body数据存储起来 |
|||
String bodyStr = getBodyString(request); |
|||
body = bodyStr.getBytes(Charset.defaultCharset()); |
|||
System.out.println(new String(body, Charset.defaultCharset()) + "+**+*+*+*++*+*+*+"); |
|||
|
|||
|
|||
} |
|||
|
|||
/** |
|||
* 获取请求Body |
|||
* |
|||
* @param request request |
|||
* @return String |
|||
*/ |
|||
public String getBodyString(final ServletRequest request) { |
|||
try { |
|||
return inputStream2String(request.getInputStream()); |
|||
} catch (IOException e) { |
|||
log.error("", e); |
|||
throw new RuntimeException(e); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取请求Body |
|||
* |
|||
* @return String |
|||
*/ |
|||
public String getBodyString() { |
|||
final InputStream inputStream = new ByteArrayInputStream(body); |
|||
|
|||
return inputStream2String(inputStream); |
|||
} |
|||
|
|||
/** |
|||
* 将inputStream里的数据读取出来并转换成字符串 |
|||
* |
|||
* @param inputStream inputStream |
|||
* @return String |
|||
*/ |
|||
private String inputStream2String(InputStream inputStream) { |
|||
StringBuilder sb = new StringBuilder(); |
|||
BufferedReader reader = null; |
|||
|
|||
try { |
|||
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset())); |
|||
String line; |
|||
while ((line = reader.readLine()) != null) { |
|||
sb.append(line); |
|||
} |
|||
} catch (IOException e) { |
|||
log.error("", e); |
|||
throw new RuntimeException(e); |
|||
} finally { |
|||
if (reader != null) { |
|||
try { |
|||
reader.close(); |
|||
} catch (IOException e) { |
|||
log.error("", e); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return sb.toString(); |
|||
} |
|||
|
|||
@Override |
|||
public BufferedReader getReader() throws IOException { |
|||
return new BufferedReader(new InputStreamReader(getInputStream())); |
|||
} |
|||
|
|||
@Override |
|||
public ServletInputStream getInputStream() throws IOException { |
|||
|
|||
final ByteArrayInputStream inputStream = new ByteArrayInputStream(body); |
|||
|
|||
return new ServletInputStream() { |
|||
@Override |
|||
public int read() throws IOException { |
|||
return inputStream.read(); |
|||
} |
|||
|
|||
@Override |
|||
public boolean isFinished() { |
|||
return false; |
|||
} |
|||
|
|||
@Override |
|||
public boolean isReady() { |
|||
return false; |
|||
} |
|||
|
|||
@Override |
|||
public void setReadListener(ReadListener readListener) { |
|||
} |
|||
}; |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
package com.example.demo.Util; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import lombok.Data; |
|||
import lombok.Getter; |
|||
import lombok.Setter; |
|||
|
|||
@Data |
|||
public class TokenPayload { |
|||
@Setter |
|||
@Getter |
|||
@JsonProperty("token") |
|||
private String token; |
|||
private String jwcode; |
|||
private String password; |
|||
} |
|||
|
@ -1,53 +1,113 @@ |
|||
//package com.example.demo.security; |
|||
// |
|||
// |
|||
//import com.example.demo.Util.JWTUtil; |
|||
//import com.example.demo.Util.RequestWrapper; |
|||
//import com.example.demo.domain.entity.Admin; |
|||
//import jakarta.servlet.FilterChain; |
|||
//import jakarta.servlet.ServletException; |
|||
//import jakarta.servlet.http.HttpServletRequest; |
|||
//import jakarta.servlet.http.HttpServletResponse; |
|||
//import org.springframework.core.annotation.Order; |
|||
//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
|||
//import org.springframework.security.core.context.SecurityContextHolder; |
|||
//import org.springframework.security.core.userdetails.UserDetails; |
|||
//import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; |
|||
//import org.springframework.stereotype.Component; |
|||
//import org.springframework.util.ObjectUtils; |
|||
//import org.springframework.util.StringUtils; |
|||
//import org.springframework.web.filter.OncePerRequestFilter; |
|||
//import java.io.IOException; |
|||
// |
|||
// |
|||
//@Component |
|||
//public class TokenFilter extends OncePerRequestFilter { |
|||
// @Override |
|||
// protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { |
|||
// // 取Token 生成登录信息 |
|||
//// String token = request.getHeader("token"); |
|||
// String token = new RequestWrapper(request).getBodyString(); |
|||
// |
|||
// System.out.println(token+"123132132"); |
|||
// |
|||
// // token不为空 |
|||
// if (StringUtils.hasText(token)){ |
|||
// try { |
|||
// UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class); |
|||
// if ( ! ObjectUtils.isEmpty(userDetails)) { |
|||
// // 将这个用户注册到Security中 |
|||
// UsernamePasswordAuthenticationToken authenticationToken |
|||
// = new UsernamePasswordAuthenticationToken( |
|||
// userDetails, null, |
|||
// userDetails.getAuthorities()); |
|||
// authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); |
|||
// SecurityContextHolder.getContext().setAuthentication(authenticationToken); |
|||
// } |
|||
// } catch (Exception e) { |
|||
// e.printStackTrace(); |
|||
// // Token无效, |
|||
// } |
|||
// } |
|||
// // 过滤器放行 |
|||
// filterChain.doFilter(request, response); |
|||
// } |
|||
//} |
|||
package com.example.demo.security; |
|||
|
|||
|
|||
|
|||
import com.example.demo.Util.JWTUtil; |
|||
import com.example.demo.Util.TokenPayload; |
|||
import com.example.demo.domain.entity.Admin; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import jakarta.servlet.FilterChain; |
|||
import jakarta.servlet.ServletException; |
|||
import jakarta.servlet.http.HttpServletRequest; |
|||
import jakarta.servlet.http.HttpServletResponse; |
|||
|
|||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
|||
import org.springframework.security.core.context.SecurityContextHolder; |
|||
import org.springframework.security.core.userdetails.UserDetails; |
|||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; |
|||
|
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.util.ObjectUtils; |
|||
import org.springframework.util.StringUtils; |
|||
import org.springframework.web.filter.OncePerRequestFilter; |
|||
|
|||
import java.io.IOException; |
|||
import java.io.InputStream; |
|||
|
|||
@Component |
|||
public class TokenFilter extends OncePerRequestFilter { |
|||
@Override |
|||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { |
|||
// 取Token 生成登录信息 |
|||
String token = request.getHeader("token"); |
|||
// token不为空 |
|||
if (StringUtils.hasText(token)){ |
|||
// jwt解密 |
|||
try { |
|||
UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class); |
|||
if ( ! ObjectUtils.isEmpty(userDetails)) { |
|||
// 将这个用户注册到Security中 |
|||
UsernamePasswordAuthenticationToken authenticationToken |
|||
// 确保请求体只被读取一次 |
|||
boolean hasRequestBody = "POST".equals(request.getMethod()); |
|||
if (hasRequestBody) { |
|||
// 获取输入流 |
|||
try (InputStream inputStream = request.getInputStream()) { |
|||
// 使用Jackson ObjectMapper解析JSON |
|||
ObjectMapper objectMapper = new ObjectMapper(); |
|||
TokenPayload tokenPayload = objectMapper.readValue(inputStream, TokenPayload.class); |
|||
|
|||
= new UsernamePasswordAuthenticationToken( |
|||
userDetails, null, |
|||
userDetails.getAuthorities()); |
|||
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); |
|||
SecurityContextHolder.getContext().setAuthentication(authenticationToken); |
|||
// 检查tokenPayload中是否存在token属性,并且这个属性不为空 |
|||
String token = tokenPayload.getToken(); |
|||
if (StringUtils.hasText(token)) { |
|||
try { |
|||
UserDetails userDetails = JWTUtil.getUserDetailsList(token, Admin.class); |
|||
if (!ObjectUtils.isEmpty(userDetails)) { |
|||
// 将这个用户注册到Security中 |
|||
UsernamePasswordAuthenticationToken authenticationToken |
|||
= new UsernamePasswordAuthenticationToken( |
|||
userDetails, null, |
|||
userDetails.getAuthorities()); |
|||
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); |
|||
SecurityContextHolder.getContext().setAuthentication(authenticationToken); |
|||
} |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
// Token无效,可以在这里添加相应的处理逻辑,例如返回401状态码等 |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
// Token无效, |
|||
} |
|||
} |
|||
// 过滤器放行 |
|||
filterChain.doFilter(request, response); |
|||
} |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue