feat: 项目初始化
This commit is contained in:
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
HELP.md
|
||||||
|
target/
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
42
dolphin-commons/dolphin-common-core/pom.xml
Normal file
42
dolphin-commons/dolphin-common-core/pom.xml
Normal 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>
|
||||||
@ -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";
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
59
dolphin-commons/dolphin-common-security/pom.xml
Normal file
59
dolphin-commons/dolphin-common-security/pom.xml
Normal 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>
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package day.gitlab.dolphin.common.security;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
public interface AuthenticationInitialize {
|
||||||
|
|
||||||
|
Authentication initialize(HttpServletRequest request);
|
||||||
|
}
|
||||||
@ -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);
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
}
|
||||||
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 {
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package day.gitlab.dolphin.common.security.annotation;
|
||||||
|
|
||||||
|
public enum AuthorityType {
|
||||||
|
AND,
|
||||||
|
OR
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package day.gitlab.dolphin.common.security.exception;
|
||||||
|
|
||||||
|
public class NotLoginException extends AuthenticationException{
|
||||||
|
|
||||||
|
public NotLoginException() {
|
||||||
|
super(401, "Unauthorized");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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
18
dolphin-commons/pom.xml
Normal 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>
|
||||||
91
dolphin-compose/pom.xml
Normal file
91
dolphin-compose/pom.xml
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?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-compose</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Project -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>day.gitlab</groupId>
|
||||||
|
<artifactId>dolphin-common-security</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>day.gitlab</groupId>
|
||||||
|
<artifactId>dolphin-module-rbac</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Spring Boot -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- JDBC Drivers -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oracle.database.jdbc</groupId>
|
||||||
|
<artifactId>ojdbc11</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- Lombok -->
|
||||||
|
<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>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package day.gitlab.dolphin;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class DolphinApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(DolphinApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package day.gitlab.dolphin.authorize;
|
||||||
|
|
||||||
|
import day.gitlab.dolphin.common.security.AuthenticationProvider;
|
||||||
|
import day.gitlab.dolphin.common.security.UserPrincipal;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DolphinAuthenticationProvider implements AuthenticationProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserPrincipal getUserPrincipal(String userId) {
|
||||||
|
UserPrincipal userPrincipal = new UserPrincipal();
|
||||||
|
userPrincipal.setId(userId);
|
||||||
|
userPrincipal.setUsername(userId);
|
||||||
|
userPrincipal.setNickname(userId);
|
||||||
|
return userPrincipal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getUserAuthorities(String userId) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
21
dolphin-compose/src/main/resources/application.yml
Normal file
21
dolphin-compose/src/main/resources/application.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
servlet:
|
||||||
|
context-path: /
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: dolphin-compose
|
||||||
|
datasource:
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
driver-class-name: org.postgresql.Driver
|
||||||
|
url: jdbc:postgresql://110.42.60.129:10002/postgres
|
||||||
|
username: postgres
|
||||||
|
password: postgres
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: 110.42.60.129
|
||||||
|
port: 10001
|
||||||
|
database: 0
|
||||||
|
password: 123456
|
||||||
|
|
||||||
|
|
||||||
58
dolphin-modules/dolphin-module-rbac/pom.xml
Normal file
58
dolphin-modules/dolphin-module-rbac/pom.xml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?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-modules</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>dolphin-module-rbac</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>day.gitlab</groupId>
|
||||||
|
<artifactId>dolphin-common-security</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-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mybatis-flex</groupId>
|
||||||
|
<artifactId>mybatis-flex-spring-boot3-starter</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>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package day.gitlab.dolphin.rbac.controller;
|
||||||
|
|
||||||
|
import day.gitlab.dolphin.rbac.service.RegionService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/region")
|
||||||
|
public class RegionController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RegionService regionService;
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
package day.gitlab.dolphin.rbac.entity;
|
||||||
|
|
||||||
|
import com.mybatisflex.annotation.Id;
|
||||||
|
import com.mybatisflex.annotation.KeyType;
|
||||||
|
import com.mybatisflex.annotation.Table;
|
||||||
|
import com.mybatisflex.core.keygen.KeyGenerators;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Table("sys_rbac_region")
|
||||||
|
public class Region {
|
||||||
|
|
||||||
|
@Id(keyType = KeyType.Generator, value = KeyGenerators.flexId)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String parentId;
|
||||||
|
|
||||||
|
private String parentCode;
|
||||||
|
|
||||||
|
private String rootId;
|
||||||
|
|
||||||
|
private String rootCode;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
private String extCode;
|
||||||
|
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private Timestamp createTime;
|
||||||
|
|
||||||
|
private Timestamp updateTime;
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package day.gitlab.dolphin.rbac.entity;
|
||||||
|
|
||||||
|
import com.mybatisflex.annotation.Id;
|
||||||
|
import com.mybatisflex.annotation.KeyType;
|
||||||
|
import com.mybatisflex.annotation.Table;
|
||||||
|
import com.mybatisflex.core.keygen.KeyGenerators;
|
||||||
|
|
||||||
|
@Table("sys_rbac_user")
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@Id(keyType = KeyType.Generator, value = KeyGenerators.flexId)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String nickname;
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package day.gitlab.dolphin.rbac.mapper;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.BaseMapper;
|
||||||
|
import day.gitlab.dolphin.rbac.entity.Region;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface RegionMapper extends BaseMapper<Region> {
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package day.gitlab.dolphin.rbac.service;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.service.IService;
|
||||||
|
import day.gitlab.dolphin.rbac.entity.Region;
|
||||||
|
|
||||||
|
public interface RegionService extends IService<Region> {
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package day.gitlab.dolphin.rbac.service.impl;
|
||||||
|
|
||||||
|
import com.mybatisflex.spring.service.impl.ServiceImpl;
|
||||||
|
import day.gitlab.dolphin.rbac.entity.Region;
|
||||||
|
import day.gitlab.dolphin.rbac.mapper.RegionMapper;
|
||||||
|
import day.gitlab.dolphin.rbac.service.RegionService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> implements RegionService {
|
||||||
|
}
|
||||||
17
dolphin-modules/pom.xml
Normal file
17
dolphin-modules/pom.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?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-modules</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>dolphin-module-rbac</module>
|
||||||
|
</modules>
|
||||||
|
</project>
|
||||||
102
pom.xml
Normal file
102
pom.xml
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?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>
|
||||||
|
|
||||||
|
<groupId>day.gitlab</groupId>
|
||||||
|
<artifactId>dolphin-backend</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>dolphin-backend</name>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>25</java.version>
|
||||||
|
<spring-boot.version>3.5.8</spring-boot.version>
|
||||||
|
<mybatis-flex.version>1.11.4</mybatis-flex.version>
|
||||||
|
<jjwt.version>0.13.0</jjwt.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>dolphin-commons</module>
|
||||||
|
<module>dolphin-modules</module>
|
||||||
|
<module>dolphin-compose</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<!-- Spring -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- MyBatis Flex -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mybatis-flex</groupId>
|
||||||
|
<artifactId>mybatis-flex-dependencies</artifactId>
|
||||||
|
<version>${mybatis-flex.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- JWT -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>${jjwt.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>${jjwt.version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>${jjwt.version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webmvc</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jdbc-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webmvc-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</project>
|
||||||
Reference in New Issue
Block a user