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; |
package com.example.demo.security; |
||||
|
|
||||
|
|
||||
|
|
||||
import com.example.demo.Util.JWTUtil; |
import com.example.demo.Util.JWTUtil; |
||||
|
import com.example.demo.Util.TokenPayload; |
||||
import com.example.demo.domain.entity.Admin; |
import com.example.demo.domain.entity.Admin; |
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import jakarta.servlet.FilterChain; |
import jakarta.servlet.FilterChain; |
||||
import jakarta.servlet.ServletException; |
import jakarta.servlet.ServletException; |
||||
import jakarta.servlet.http.HttpServletRequest; |
import jakarta.servlet.http.HttpServletRequest; |
||||
import jakarta.servlet.http.HttpServletResponse; |
import jakarta.servlet.http.HttpServletResponse; |
||||
|
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
||||
import org.springframework.security.core.context.SecurityContextHolder; |
import org.springframework.security.core.context.SecurityContextHolder; |
||||
import org.springframework.security.core.userdetails.UserDetails; |
import org.springframework.security.core.userdetails.UserDetails; |
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; |
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; |
||||
|
|
||||
import org.springframework.stereotype.Component; |
import org.springframework.stereotype.Component; |
||||
import org.springframework.util.ObjectUtils; |
import org.springframework.util.ObjectUtils; |
||||
import org.springframework.util.StringUtils; |
import org.springframework.util.StringUtils; |
||||
import org.springframework.web.filter.OncePerRequestFilter; |
import org.springframework.web.filter.OncePerRequestFilter; |
||||
|
|
||||
import java.io.IOException; |
import java.io.IOException; |
||||
|
import java.io.InputStream; |
||||
|
|
||||
@Component |
@Component |
||||
public class TokenFilter extends OncePerRequestFilter { |
public class TokenFilter extends OncePerRequestFilter { |
||||
@Override |
@Override |
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { |
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); |
filterChain.doFilter(request, response); |
||||
} |
} |
||||
} |
|
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue