add
This commit is contained in:
11
backend/src/main/java/com/flower/security/AdminOnly.java
Normal file
11
backend/src/main/java/com/flower/security/AdminOnly.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.flower.security;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface AdminOnly {
|
||||
}
|
||||
29
backend/src/main/java/com/flower/security/AuthContext.java
Normal file
29
backend/src/main/java/com/flower/security/AuthContext.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package com.flower.security;
|
||||
|
||||
import com.flower.user.User;
|
||||
|
||||
public class AuthContext {
|
||||
private static final ThreadLocal<User> HOLDER = new ThreadLocal<>();
|
||||
private static final ThreadLocal<String> TOKEN = new ThreadLocal<>();
|
||||
|
||||
public static void set(User user) {
|
||||
HOLDER.set(user);
|
||||
}
|
||||
|
||||
public static User get() {
|
||||
return HOLDER.get();
|
||||
}
|
||||
|
||||
public static void setToken(String token) {
|
||||
TOKEN.set(token);
|
||||
}
|
||||
|
||||
public static String getToken() {
|
||||
return TOKEN.get();
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
HOLDER.remove();
|
||||
TOKEN.remove();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.flower.security;
|
||||
|
||||
import com.flower.common.ApiException;
|
||||
import com.flower.user.Session;
|
||||
import com.flower.user.SessionRepository;
|
||||
import com.flower.user.User;
|
||||
import com.flower.user.UserRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class AuthInterceptor implements HandlerInterceptor {
|
||||
private final SessionRepository sessionRepository;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public AuthInterceptor(SessionRepository sessionRepository, UserRepository userRepository) {
|
||||
this.sessionRepository = sessionRepository;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||
if (!(handler instanceof HandlerMethod)) {
|
||||
return true;
|
||||
}
|
||||
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
|
||||
return true;
|
||||
}
|
||||
HandlerMethod method = (HandlerMethod) handler;
|
||||
if (method.hasMethodAnnotation(PublicEndpoint.class)) {
|
||||
return true;
|
||||
}
|
||||
String token = extractToken(request);
|
||||
if (!StringUtils.hasText(token)) {
|
||||
throw new ApiException(401, "未登录");
|
||||
}
|
||||
Optional<Session> session = sessionRepository.findByTokenAndExpiredFalse(token);
|
||||
if (!session.isPresent()) {
|
||||
throw new ApiException(401, "登录已过期");
|
||||
}
|
||||
User user = userRepository.findById(session.get().getUserId())
|
||||
.orElseThrow(() -> new ApiException(404, "用户不存在"));
|
||||
if (Boolean.TRUE.equals(user.getDisabled())) {
|
||||
throw new ApiException(403, "账号已禁用");
|
||||
}
|
||||
AuthContext.set(user);
|
||||
AuthContext.setToken(token);
|
||||
if (method.hasMethodAnnotation(AdminOnly.class) || method.getBeanType().isAnnotationPresent(AdminOnly.class)) {
|
||||
if (!"ADMIN".equals(user.getRole())) {
|
||||
throw new ApiException(403, "无权限");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
|
||||
AuthContext.clear();
|
||||
}
|
||||
|
||||
private String extractToken(HttpServletRequest request) {
|
||||
String auth = request.getHeader("Authorization");
|
||||
if (StringUtils.hasText(auth) && auth.startsWith("Bearer ")) {
|
||||
return auth.substring(7);
|
||||
}
|
||||
return request.getHeader("X-Token");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.flower.security;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface PublicEndpoint {
|
||||
}
|
||||
Reference in New Issue
Block a user