feat: 项目初始化

This commit is contained in:
2025-11-28 17:35:39 +08:00
parent 3ea0202709
commit 32fba5f65d
41 changed files with 1305 additions and 0 deletions

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>day.gitlab</groupId>
<artifactId>dolphin-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dolphin-common-core</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,8 @@
package day.gitlab.dolphin.common.core.constants;
public class Constants {
public static final String SUCCESS = "success";
public static final String FAILURE = "failure";
}

View File

@ -0,0 +1,55 @@
package day.gitlab.dolphin.common.core.entity;
import day.gitlab.dolphin.common.core.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.function.Supplier;
import static day.gitlab.dolphin.common.core.constants.Constants.FAILURE;
import static day.gitlab.dolphin.common.core.constants.Constants.SUCCESS;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private int code;
private String message;
private Object data;
public static Result success() {
return Result.builder().code(200).message(SUCCESS).build();
}
public static Result success(Object data) {
Result result = Result.builder().code(200).message(SUCCESS).build();
if (data instanceof Supplier) {
result.setData(((Supplier<?>) data).get());
} else {
result.setData(data);
}
return result;
}
public static Result failure() {
return Result.builder().code(500).message(FAILURE).build();
}
public static Result failure(String message) {
return Result.builder().code(500).message(message).build();
}
public static Result failure(int code, String message) {
return Result.builder().code(code).message(message).build();
}
public static Result failure(BusinessException businessException) {
return Result.builder().code(businessException.getCode()).message(businessException.getMessage()).build();
}
}

View File

@ -0,0 +1,14 @@
package day.gitlab.dolphin.common.core.exception;
import lombok.Getter;
@Getter
public class BusinessException extends RuntimeException {
private final int code;
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
}

View File

@ -0,0 +1,21 @@
package day.gitlab.dolphin.common.core.exception;
import day.gitlab.dolphin.common.core.entity.Result;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@Component
@ControllerAdvice
public class GlobalExceptionAdvice {
@ExceptionHandler(value = BusinessException.class)
public Result handleBusinessException(BusinessException e) {
return Result.failure(e);
}
@ExceptionHandler(value = Exception.class)
public Result handleException(Exception e) {
return Result.failure(e.getMessage());
}
}

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>day.gitlab</groupId>
<artifactId>dolphin-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dolphin-common-security</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>day.gitlab</groupId>
<artifactId>dolphin-common-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,36 @@
package day.gitlab.dolphin.common.security;
import lombok.Getter;
import java.util.List;
@Getter
public class Authentication {
private final UserPrincipal userPrincipal;
private final List<String> userAuthorities;
public Authentication(UserPrincipal userPrincipal, List<String> userAuthorities) {
this.userPrincipal = userPrincipal;
this.userAuthorities = userAuthorities;
}
public boolean hasAllAuthorities(String[] userAuthorities) {
for (String userAuthority : userAuthorities) {
if (!this.userAuthorities.contains(userAuthority)) {
return false;
}
}
return true;
}
public boolean hasAnyAuthorities(String[] userAuthorities) {
for (String userAuthority : userAuthorities) {
if (this.userAuthorities.contains(userAuthority)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,58 @@
package day.gitlab.dolphin.common.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import day.gitlab.dolphin.common.core.entity.Result;
import day.gitlab.dolphin.common.core.exception.BusinessException;
import day.gitlab.dolphin.common.security.annotation.AuthorityIgnoreInitializer;
import day.gitlab.dolphin.common.security.config.SecurityConfig;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@Component
public class AuthenticationFilter extends OncePerRequestFilter {
private final SecurityConfig securityConfig;
private final AuthorityIgnoreInitializer authorityIgnoreInitializer;
private final AuthenticationInitialize authenticationInitialize;
public AuthenticationFilter(SecurityConfig securityConfig,
AuthorityIgnoreInitializer authorityIgnoreInitializer,
AuthenticationInitialize authenticationInitialize) {
this.securityConfig = securityConfig;
this.authorityIgnoreInitializer = authorityIgnoreInitializer;
this.authenticationInitialize = authenticationInitialize;
}
@Override
protected void doFilterInternal(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain) throws ServletException, IOException {
// 在未启用或是忽略校验的地址时直接放行
if (!securityConfig.isEnabled() || authorityIgnoreInitializer.isIgnoreUrl(request)) {
filterChain.doFilter(request, response);
}
try {
Authentication initialize = authenticationInitialize.initialize(request);
SecurityContextHolder.setAuthentication(initialize);
filterChain.doFilter(request, response);
} catch (BusinessException e) {
response.setStatus(e.getCode());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
response.getWriter().write(new ObjectMapper().writeValueAsString(Result.failure(e)));
} finally {
SecurityContextHolder.clearAuthentication();
}
}
}

View File

@ -0,0 +1,8 @@
package day.gitlab.dolphin.common.security;
import jakarta.servlet.http.HttpServletRequest;
public interface AuthenticationInitialize {
Authentication initialize(HttpServletRequest request);
}

View File

@ -0,0 +1,10 @@
package day.gitlab.dolphin.common.security;
import java.util.List;
public interface AuthenticationProvider {
UserPrincipal getUserPrincipal(String userId);
List<String> getUserAuthorities(String userId);
}

View File

@ -0,0 +1,20 @@
package day.gitlab.dolphin.common.security;
public class SecurityContextHolder {
private static final ThreadLocal<Authentication> CONTEXT = new ThreadLocal<>();
private SecurityContextHolder() {}
public static Authentication getAuthentication() {
return CONTEXT.get();
}
public static void setAuthentication(Authentication authentication) {
CONTEXT.set(authentication);
}
public static void clearAuthentication() {
CONTEXT.remove();
}
}

View File

@ -0,0 +1,19 @@
package day.gitlab.dolphin.common.security;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserPrincipal {
private String id;
private String username;
private String nickname;
}

View File

@ -0,0 +1,18 @@
package day.gitlab.dolphin.common.security.annotation;
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 AuthorityCheck {
AuthorityType type() default AuthorityType.AND;
String[] value();
}

View File

@ -0,0 +1,32 @@
package day.gitlab.dolphin.common.security.annotation;
import day.gitlab.dolphin.common.security.Authentication;
import day.gitlab.dolphin.common.security.SecurityContextHolder;
import day.gitlab.dolphin.common.security.exception.NotAuthorityException;
import day.gitlab.dolphin.common.security.exception.NotLoginException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class AuthorityCheckAspect {
@Before("@annotation(authorityCheck)")
public void check(JoinPoint joinPoint, AuthorityCheck authorityCheck) {
Authentication authentication = SecurityContextHolder.getAuthentication();
if (authentication == null) {
throw new NotLoginException();
}
// AuthorityCheck的type如果是AND输出1
if (authorityCheck.type() == AuthorityType.AND) {
if (!authentication.hasAllAuthorities(authorityCheck.value())) {
throw new NotAuthorityException(authorityCheck.value());
}
} else if (authorityCheck.type() == AuthorityType.OR) {
if (!authentication.hasAnyAuthorities(authorityCheck.value())) {
throw new NotAuthorityException(authorityCheck.value());
}
}
}
}

View File

@ -0,0 +1,14 @@
package day.gitlab.dolphin.common.security.annotation;
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 AuthorityIgnore {
}

View File

@ -0,0 +1,101 @@
package day.gitlab.dolphin.common.security.annotation;
import day.gitlab.dolphin.common.security.config.SecurityConfig;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
public class AuthorityIgnoreInitializer implements ApplicationContextAware {
private final List<IgnoreUrl> ignoreUrls = new ArrayList<>();
private SecurityConfig securityConfig;
@Override
public void setApplicationContext(@NonNull ApplicationContext ctx) throws BeansException {
String contextPath = ctx.getEnvironment().getProperty("server.servlet.context-path");
RequestMappingHandlerMapping requestMappingHandlerMapping = ctx.getBean(RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
if (StringUtils.hasText(securityConfig.getIgnoreUrls())) {
Arrays.stream(securityConfig.getIgnoreUrls().split(","))
.filter(StringUtils::hasText)
.map(s -> {
String prefixUrl = StringUtils.hasLength(contextPath) ? contextPath : "";
prefixUrl = prefixUrl.endsWith("/") ? prefixUrl.substring(0, prefixUrl.length() - 1) : prefixUrl;
return s.startsWith("/") ? prefixUrl + s : prefixUrl + "/" + s;
})
.map(IgnoreUrl::new)
.forEach(url -> this.ignoreUrls.add(url));
}
for (RequestMappingInfo mappingInfo : handlerMethods.keySet()) {
HandlerMethod handlerMethod = handlerMethods.get(mappingInfo);
Class<?> beanClass = handlerMethod.getBeanType();
RequestMapping requestMapping = handlerMethod.getMethodAnnotation(RequestMapping.class);
if (requestMapping == null) {
continue;
}
AuthorityIgnore authorityIgnore = handlerMethod.getMethodAnnotation(AuthorityIgnore.class);
if (authorityIgnore == null && !beanClass.isAnnotationPresent(AuthorityIgnore.class)) {
continue;
}
System.out.println("beanClass:" + beanClass.getCanonicalName());
System.out.println("method:" + handlerMethod.getMethod().getName() + " -> " + mappingInfo.getPatternValues());
List<String> urlPrefix = Arrays.stream(requestMapping.method())
.map(RequestMethod::name)
.map(StringBuffer::new)
.map(sb -> sb.append(":"))
.map(sb -> StringUtils.hasText(contextPath) ? sb.append(contextPath) : sb)
.map(StringBuffer::toString)
.map(sb -> sb.endsWith("/") ? sb.substring(0, sb.length() - 1) : sb)
.collect(Collectors.toList());
if (urlPrefix.isEmpty()) {
String prefixUrl = StringUtils.hasText(contextPath) ? contextPath : "/";
if (prefixUrl.endsWith("/")) {
prefixUrl = prefixUrl.substring(0, prefixUrl.length() - 1);
}
urlPrefix.add(prefixUrl);
}
urlPrefix.stream()
.flatMap(sub -> mappingInfo.getPatternValues().stream().filter(StringUtils::hasText).map(s -> sub + s))
.map(IgnoreUrl::new)
.forEach(url -> this.ignoreUrls.add(url));
System.out.println("ignoreUrls: " + ignoreUrls);
}
}
public boolean isIgnoreUrl(HttpServletRequest request) {
String method = request.getMethod();
String url = request.getRequestURI();
return this.ignoreUrls.stream().anyMatch(ignoreUrl -> ignoreUrl.isIgnoreUrl(method, url));
}
@Autowired
public void setSecurityConfig(SecurityConfig securityConfig) {
this.securityConfig = securityConfig;
}
}

View File

@ -0,0 +1,6 @@
package day.gitlab.dolphin.common.security.annotation;
public enum AuthorityType {
AND,
OR
}

View File

@ -0,0 +1,54 @@
package day.gitlab.dolphin.common.security.annotation;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.AntPathMatcher;
@Setter
@Getter
public class IgnoreUrl {
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
private String method;
private String url;
public IgnoreUrl(String url) {
String urlUpperCase = url.toUpperCase();
if (urlUpperCase.startsWith("GET:")) {
this.method = "GET";
} else if (urlUpperCase.startsWith("HEAD:")) {
this.method = "HEAD";
} else if (urlUpperCase.startsWith("POST:")) {
this.method = "POST";
} else if (urlUpperCase.startsWith("PUT:")) {
this.method = "PUT";
} else if (urlUpperCase.startsWith("PATCH:")) {
this.method = "PATCH";
} else if (urlUpperCase.startsWith("DELETE:")) {
this.method = "DELETE";
} else if (urlUpperCase.startsWith("OPTIONS:")) {
this.method = "OPTIONS";
} else if (urlUpperCase.startsWith("TRACE:")) {
this.method = "TRACE";
} else {
this.method = null;
}
this.url = url.substring(urlUpperCase.indexOf(":") + 1);
}
public boolean isIgnoreUrl(String method, String url) {
if (!PATH_MATCHER.match(this.url, url)) {
return false;
}
return this.method == null || this.method.equalsIgnoreCase(method);
}
@Override
public String toString() {
return method == null ? url : method + ":" + url;
}
}

View File

@ -0,0 +1,24 @@
package day.gitlab.dolphin.common.security.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Setter
@Getter
@Component
@ConfigurationProperties("dolphin.security")
public class SecurityConfig {
private boolean enabled = true;
private String ignoreUrls = "";
private String secret = "dolphin";
private long expire = 3600 * 1000L;
private long refreshTokenExpire = 7 * 24 * 3600 * 1000L;
}

View File

@ -0,0 +1,12 @@
package day.gitlab.dolphin.common.security.exception;
import day.gitlab.dolphin.common.core.exception.BusinessException;
import lombok.Getter;
@Getter
public class AuthenticationException extends BusinessException {
public AuthenticationException(int code, String message) {
super(code, message);
}
}

View File

@ -0,0 +1,14 @@
package day.gitlab.dolphin.common.security.exception;
import lombok.Getter;
@Getter
public class InvalidTokenException extends AuthenticationException {
private final String token;
public InvalidTokenException(String token) {
super(401, "Unauthorized: Invalid token");
this.token = token;
}
}

View File

@ -0,0 +1,14 @@
package day.gitlab.dolphin.common.security.exception;
import lombok.Getter;
@Getter
public class NotAuthorityException extends AuthenticationException {
private final String[] userAuthorities;
public NotAuthorityException(String[] userAuthorities) {
super(403, "Forbidden: Insufficient permissions");
this.userAuthorities = userAuthorities;
}
}

View File

@ -0,0 +1,8 @@
package day.gitlab.dolphin.common.security.exception;
public class NotLoginException extends AuthenticationException{
public NotLoginException() {
super(401, "Unauthorized");
}
}

View File

@ -0,0 +1,20 @@
package day.gitlab.dolphin.common.security.exception;
import lombok.Getter;
import java.util.Date;
@Getter
public class TokenExpiredException extends AuthenticationException {
private final String token;
private final Date expiration;
public TokenExpiredException(String token, Date expiration) {
super(401, "Unauthorized: Token expired");
this.token = token;
this.expiration = expiration;
}
}

View File

@ -0,0 +1,70 @@
package day.gitlab.dolphin.common.security.jwt;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.StringUtils;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;
public class Jwt {
private final String secret;
private final long expire;
private final long refreshTokenExpire;
public Jwt(String secret, long expire, long refreshTokenExpire) {
this.secret = secret;
this.expire = expire;
this.refreshTokenExpire = refreshTokenExpire;
}
public String getTokenFromRequest(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (StringUtils.hasText(token) && token.startsWith("Bearer ")) {
return token.substring(7);
}
return null;
}
public String generateAccessToken(String userId) {
return Jwts.builder()
.subject(userId)
.id(UUID.randomUUID().toString())
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + expire))
.claim("type", "access")
.signWith(getSigningKey())
.compact();
}
public String generateRefreshToken(String userId) {
return Jwts.builder()
.subject(userId)
.id(UUID.randomUUID().toString())
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + refreshTokenExpire))
.claim("type", "refresh")
.signWith(getSigningKey())
.compact();
}
public Claims parseToken(String token) {
return Jwts.parser()
.verifyWith(getSigningKey())
.build()
.parseSignedClaims(token)
.getPayload();
}
private SecretKey getSigningKey() {
byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
return Keys.hmacShaKeyFor(keyBytes);
}
}

View File

@ -0,0 +1,91 @@
package day.gitlab.dolphin.common.security.jwt;
import com.fasterxml.jackson.databind.ObjectMapper;
import day.gitlab.dolphin.common.security.Authentication;
import day.gitlab.dolphin.common.security.AuthenticationInitialize;
import day.gitlab.dolphin.common.security.AuthenticationProvider;
import day.gitlab.dolphin.common.security.UserPrincipal;
import day.gitlab.dolphin.common.security.config.SecurityConfig;
import day.gitlab.dolphin.common.security.exception.InvalidTokenException;
import day.gitlab.dolphin.common.security.exception.NotLoginException;
import day.gitlab.dolphin.common.security.exception.TokenExpiredException;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Component
public class JwtAuthenticationInitialize implements AuthenticationInitialize {
private final SecurityConfig securityConfig;
private final StringRedisTemplate stringRedisTemplate;
private final AuthenticationProvider authenticationProvider;
public JwtAuthenticationInitialize(SecurityConfig securityConfig,
StringRedisTemplate stringRedisTemplate,
AuthenticationProvider authenticationProvider) {
this.securityConfig = securityConfig;
this.stringRedisTemplate = stringRedisTemplate;
this.authenticationProvider = authenticationProvider;
}
@Override
public Authentication initialize(HttpServletRequest request) {
Jwt jwt = new Jwt(securityConfig.getSecret(), securityConfig.getExpire(), securityConfig.getRefreshTokenExpire());
// 1、获取Token
String token = jwt.getTokenFromRequest(request);
if (token == null) {
throw new NotLoginException();
}
// 2、解析Token获取用户ID
String userId;
Date expiration;
try {
Claims claims = jwt.parseToken(token);
userId = claims.getSubject();
expiration = claims.getExpiration();
Objects.requireNonNull(userId);
Objects.requireNonNull(expiration);
} catch (Exception e) {
throw new InvalidTokenException(token);
}
// 3、判断是否过期
if (expiration.before(new Date())) {
throw new TokenExpiredException(token, expiration);
}
// 4、从Redis或数据库中加载用户信息
UserPrincipal userPrincipal;
List<String> userAuthorities;
try {
String userPrincipalJson = stringRedisTemplate.opsForValue().get("dolphin:user:info:" + userId);
ObjectMapper objectMapper = new ObjectMapper();
if (!StringUtils.hasText(userPrincipalJson)) {
userPrincipal = authenticationProvider.getUserPrincipal(userId);
stringRedisTemplate.opsForValue().set("dolphin:user:info:" + userId, objectMapper.writeValueAsString(userPrincipal));
} else {
userPrincipal = objectMapper.readValue(userPrincipalJson, UserPrincipal.class);
}
String userAuthJson = stringRedisTemplate.opsForValue().get("dolphin:user:auth:" + userId);
if (!StringUtils.hasText(userAuthJson)) {
userAuthorities = authenticationProvider.getUserAuthorities(userId);
stringRedisTemplate.opsForValue().set("dolphin:user:auth:" + userId, objectMapper.writeValueAsString(userAuthorities));
} else {
List<?> list = objectMapper.readValue(userAuthJson, List.class);
userAuthorities = list.stream().map(Object::toString).collect(Collectors.toList());
}
} catch (Exception e) {
throw new InvalidTokenException(token);
}
return new Authentication(userPrincipal, userAuthorities);
}
}

18
dolphin-commons/pom.xml Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>day.gitlab</groupId>
<artifactId>dolphin-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>dolphin-commons</artifactId>
<packaging>pom</packaging>
<modules>
<module>dolphin-common-core</module>
<module>dolphin-common-security</module>
</modules>
</project>