diff --git a/pom.xml b/pom.xml index 6435a33..d3b6581 100644 --- a/pom.xml +++ b/pom.xml @@ -38,12 +38,13 @@ 11.8 2.13.3 + 2.13.3 2.0.11 3.4.3 8.0.21 42.5.0 - 2.13.3 + 4.1.1 4.5.0 2.12.2 @@ -65,7 +66,8 @@ 4.4 2.11.0 1.1.0 - + + 3.0.3 @@ -122,6 +124,16 @@ mysql-connector-java ${mysql-jdbc.version} + + com.github.xiaoymin + knife4j-spring-boot-starter + ${knife4j.version} + + + com.github.xiaoymin + knife4j-micro-spring-boot-starter + ${knife4j.version} + @@ -242,6 +254,12 @@ + + + org.apache.shardingsphere + sharding-jdbc-spring-boot-starter + ${shardingsphere.version} + diff --git a/server/zyjblogs-gateway/pom.xml b/server/zyjblogs-gateway/pom.xml index 71cc304..d67c88b 100644 --- a/server/zyjblogs-gateway/pom.xml +++ b/server/zyjblogs-gateway/pom.xml @@ -37,7 +37,7 @@ commons-pool2 - zyjblogs-web-spring-boot-starter + zyjblogs-common-spring-boot-starter cn.zyjblogs.starter @@ -46,11 +46,11 @@ - - - - - + + + + + @@ -85,5 +85,10 @@ com.alibaba.csp sentinel-datasource-nacos + + + com.github.xiaoymin + knife4j-spring-boot-starter + \ No newline at end of file diff --git a/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/config/swagger/SwaggerHandler.java b/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/config/swagger/SwaggerHandler.java new file mode 100644 index 0000000..b58c505 --- /dev/null +++ b/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/config/swagger/SwaggerHandler.java @@ -0,0 +1,44 @@ +package cn.zyjblogs.config.swagger; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; +import springfox.documentation.swagger.web.UiConfiguration; + +/** + * @author zhuyijun + */ +@RestController +@RequestMapping("/swagger-resources") +public class SwaggerHandler { + + private final SwaggerResourcesProvider swaggerResources; + + private final UiConfiguration uiConfiguration; + + public SwaggerHandler(SwaggerResourcesProvider swaggerResources, UiConfiguration uiConfiguration) { + this.swaggerResources = swaggerResources; + this.uiConfiguration = uiConfiguration; + } + +// @GetMapping("/swagger-resources/configuration/security") +// public Mono> securityConfiguration() { +// return Mono.just(new ResponseEntity<>( +// Optional.ofNullable(OAuth2ResourceServerAutoConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK)); +// } + + @GetMapping("") + public Mono swaggerResources() { + return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); + } + + @GetMapping("/configuration/ui") + public Mono> uiConfiguration() { + return Mono.just(new ResponseEntity<>(uiConfiguration, HttpStatus.OK)); + } + +} diff --git a/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/config/swagger/SwaggerProvider.java b/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/config/swagger/SwaggerProvider.java new file mode 100644 index 0000000..3cd7b46 --- /dev/null +++ b/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/config/swagger/SwaggerProvider.java @@ -0,0 +1,66 @@ +package cn.zyjblogs.config.swagger; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.gateway.config.GatewayProperties; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.support.NameUtils; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import springfox.documentation.swagger.web.SwaggerResource; +import springfox.documentation.swagger.web.SwaggerResourcesProvider; +import springfox.documentation.swagger.web.UiConfiguration; +import springfox.documentation.swagger.web.UiConfigurationBuilder; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author zhuyijun + */ +@Configuration +@Primary +public class SwaggerProvider implements SwaggerResourcesProvider { + + public static final String API_URI = "/v2/api-docs"; + + private final RouteLocator routeLocator; + + private final GatewayProperties gatewayProperties; + + @Autowired + public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) { + this.routeLocator = routeLocator; + this.gatewayProperties = gatewayProperties; + } + + @Override + public List get() { + List resources = new ArrayList<>(); + List routes = new ArrayList<>(); + //取出gateway的route + routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); + //结合配置的route-路径(Path),和route过滤,只获取有效的route节点 + gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())) + .forEach(routeDefinition -> routeDefinition.getPredicates().stream() + .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()) && predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0").startsWith("/api")) + .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(), + predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") + .replace("/**", API_URI))))); + return resources; + } + + private SwaggerResource swaggerResource(String name, String location) { + SwaggerResource swaggerResource = new SwaggerResource(); + swaggerResource.setName(name); + swaggerResource.setLocation(location); + swaggerResource.setSwaggerVersion("3.0"); + return swaggerResource; + } + + @Bean + public UiConfiguration uiConfiguration() { + return UiConfigurationBuilder.builder().build(); + } + +} diff --git a/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/filter/AuthFilter.java b/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/filter/AuthFilter.java index 02c7786..e3b848c 100644 --- a/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/filter/AuthFilter.java +++ b/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/filter/AuthFilter.java @@ -1,9 +1,9 @@ package cn.zyjblogs.filter; import cn.zyjblogs.starter.common.entity.constant.HttpHeaderConstant; +import cn.zyjblogs.starter.common.entity.response.HttpCode; import cn.zyjblogs.starter.common.entity.response.ResponseObject; import cn.zyjblogs.starter.common.entity.response.ResponseResult; -import cn.zyjblogs.starter.common.entity.response.HttpCode; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; @@ -11,8 +11,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.cloud.gateway.route.Route; -import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -42,7 +40,6 @@ import java.util.List; public class AuthFilter implements GlobalFilter { private final WhiteListProperties whiteListProperties; private AntPathMatcher antPathMatcher = new AntPathMatcher(); - private String SIGNING_KEY="zyjblogs123"; @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { @@ -54,16 +51,12 @@ public class AuthFilter implements GlobalFilter { ServerHttpRequest request = build.getRequest(); ServerHttpResponse response = build.getResponse(); String token = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION); - log.debug("token:{}", token); String path = request.getURI().getPath(); - String methodType = request.getMethodValue().toLowerCase(); - Route route = (Route) exchange.getAttributes().get(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR); - String routeId = route.getId(); //白名单请求直接放行 if (isWhileList(path)) { return chain.filter(exchange); } - if (StringUtils.isEmpty(token)) { + if (token == null || StringUtils.isEmpty(token) || !token.startsWith(HttpHeaderConstant.AUTHORIZATION_TYPE)) { return getErrorMono(response, HttpCode.UNAUTHORIZED, "无访问权限"); } if (isExpired(token)) { @@ -93,15 +86,19 @@ public class AuthFilter implements GlobalFilter { * @date 2021/11/15 19:17 */ private boolean isExpired(String token) { - if (!token.startsWith(HttpHeaderConstant.AUTHORIZATION_TYPE)) { - return true; - } -// String jwt = token.replace(HttpHeaderConstant.AUTHORIZATION_TYPE + " ", ""); -// OauthClaims body = (OauthClaims) Jwts.parser().setSigningKey(SIGNING_KEY).parseClaimsJws(jwt).getBody(); -// BaseContextHandler.set(ContextDto.builder().token(jwt).userId(body.getUserId()).username(body.getUsername()).build()); +//// String jwt = token.replace(HttpHeaderConstant.AUTHORIZATION_TYPE, "").trim(); +// try { +//// PublicKey publicKeyByPath = RsaUtils.getPublicKeyByPath(rsaKeyProperties.getPubKeyPath()); +//// Claims body = new JwtParsers(false).setSigningKey(publicKeyByPath).parseClaimsJwt(jwt).getBody(); +//// log.info("{}", body); +// return false; +// } catch (Exception e) { +// return true; +// } return false; } + /** * 是否是白名单 * @@ -121,7 +118,6 @@ public class AuthFilter implements GlobalFilter { } - /** * 验证不通过时的返回 * diff --git a/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/filter/WhiteListProperties.java b/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/filter/WhiteListProperties.java index c33a06e..4fc5a45 100644 --- a/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/filter/WhiteListProperties.java +++ b/server/zyjblogs-gateway/src/main/java/cn/zyjblogs/filter/WhiteListProperties.java @@ -7,6 +7,8 @@ import java.util.List; /** * 白名单 + * + * @author zhuyijun */ @Data @ConfigurationProperties(prefix = "zyjblogs.whilelist") diff --git a/server/zyjblogs-gateway/src/main/resources/bootstrap.yml b/server/zyjblogs-gateway/src/main/resources/bootstrap.yml index e015d04..3a75a17 100644 --- a/server/zyjblogs-gateway/src/main/resources/bootstrap.yml +++ b/server/zyjblogs-gateway/src/main/resources/bootstrap.yml @@ -18,6 +18,7 @@ spring: shared-configs[0]: data-id: zyjblogs-global-${spring.profiles.active}.yml group: global + refresh: true discovery: server-addr: ${spring.cloud.nacos.config.server-addr} username: ${spring.cloud.nacos.config.username} diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/ResourceServerConfig.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/ResourceServerConfig.java index c69ef46..0813163 100644 --- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/ResourceServerConfig.java +++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/ResourceServerConfig.java @@ -4,6 +4,7 @@ import cn.zyjblogs.config.handler.ResourceAccessDeniedHandler; import cn.zyjblogs.config.handler.ResourceAuthenticationEntryPoint; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -12,14 +13,19 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.R import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.TokenStore; +/** + * @author zhuyijun + */ @Configuration @EnableResourceServer @RequiredArgsConstructor +@EnableConfigurationProperties(WhiteListProperties.class) @RefreshScope public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Value("${spring.application.name}") private String resourceId; private final TokenStore tokenStore; + private final WhiteListProperties whiteListProperties; @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { @@ -45,10 +51,12 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter { .csrf() .disable() //限制资源服务器作用范围为 "/user/**", "/demo/**" - .requestMatchers().antMatchers("/user/**", "/demo/**").and() + .requestMatchers().antMatchers("/webjars/**", "/swagger-ui.html/**", "/swagger-resources/**", "/v2/api-docs/**", "/user/**", "/demo/**", + String.join(",", whiteListProperties.getAllowPaths())) + .and() .formLogin().and() .authorizeRequests() - .antMatchers("/webjars/**", "/swagger-ui.html/**", "/swagger-resources/**", "/v2/api-docs/**") + .antMatchers("/webjars/**", "/swagger-ui.html/**", "/swagger-resources/**", "/v2/api-docs/**", String.join(",", whiteListProperties.getAllowPaths())) .permitAll() .antMatchers("/login", "/oauth/**", "/user/login", "/user/refresh/token").permitAll() //以下请求必须认证通过 diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/WhiteListProperties.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/WhiteListProperties.java new file mode 100644 index 0000000..cf054b9 --- /dev/null +++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/config/security/WhiteListProperties.java @@ -0,0 +1,18 @@ +package cn.zyjblogs.config.security; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.List; + +/** + * 白名单 + * + * @author zhuyijun + */ +@Data +@ConfigurationProperties(prefix = "zyjblogs.whilelist") +public class WhiteListProperties { + + private List allowPaths; +} diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AutoController.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AuthController.java similarity index 95% rename from server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AutoController.java rename to server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AuthController.java index 7278b61..a90dae8 100644 --- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AutoController.java +++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/AuthController.java @@ -6,6 +6,7 @@ import cn.zyjblogs.server.user.service.AuthService; import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo; import cn.zyjblogs.starter.common.entity.response.ResponseObject; import cn.zyjblogs.starter.common.entity.response.ResponseResult; +import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; @@ -17,10 +18,11 @@ import org.springframework.web.bind.annotation.RestController; /** * @author zhuyijun */ +@Api(tags = {"token管理"}) @RestController @RequiredArgsConstructor @RequestMapping("/auth") -public class AutoController { +public class AuthController { private final AuthService authService; @ApiOperation(value = "刷新token", notes = "刷新token") diff --git a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/LoginController.java b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/LoginController.java index cc3968b..252652e 100644 --- a/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/LoginController.java +++ b/server/zyjblogs-oauth/src/main/java/cn/zyjblogs/server/user/controller/LoginController.java @@ -5,6 +5,7 @@ import cn.zyjblogs.server.user.service.LoginService; import cn.zyjblogs.server.user.vo.OAuth2AccessTokenVo; import cn.zyjblogs.starter.common.entity.response.ResponseObject; import cn.zyjblogs.starter.common.entity.response.ResponseResult; +import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; @@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController; /** * @author zhuyijun */ +@Api(tags = {"登录认证管理"}) @RestController @RequiredArgsConstructor @RequestMapping("/user") diff --git a/server/zyjblogs-oauth/src/main/resources/bootstrap.yml b/server/zyjblogs-oauth/src/main/resources/bootstrap.yml index 063e93c..07f3b38 100644 --- a/server/zyjblogs-oauth/src/main/resources/bootstrap.yml +++ b/server/zyjblogs-oauth/src/main/resources/bootstrap.yml @@ -21,6 +21,7 @@ spring: shared-configs[0]: data-id: zyjblogs-global-${spring.profiles.active}.yml group: global + refresh: true discovery: server-addr: ${spring.cloud.nacos.config.server-addr} username: ${spring.cloud.nacos.config.username} diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/controller/RoleController.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/controller/RoleController.java index 183129d..c00ecb2 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/controller/RoleController.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/controller/RoleController.java @@ -8,6 +8,8 @@ import cn.zyjblogs.starter.common.entity.response.ResponseObject; import cn.zyjblogs.starter.common.entity.response.ResponseResult; import cn.zyjblogs.starter.common.utils.bean.BeanUtils; import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -21,6 +23,7 @@ import java.util.List; /** * @author zhuyijun */ +@Api(tags = {"角色管理"}) @RestController @RequestMapping("/role") @ResponseBody @@ -36,6 +39,7 @@ public class RoleController { * @author zhuyijun * @date 2022/9/19 上午12:06 */ + @ApiOperation(value = "1", notes = "通过id查询用户") @GetMapping("/id") public ResponseObject findById(@RequestParam String id) { RolePo byId = roleService.getById(id); @@ -49,12 +53,25 @@ public class RoleController { * @author zhuyijun * @date 2022/9/19 上午1:14 */ + @ApiOperation(value = "page=1&limit=10", notes = "分页查询") @GetMapping("/page") public ResponseObject> findPage(RolePageDto rolePageDto) { IPage page = roleService.findPage(rolePageDto); return ResponseResult.success(page.getTotal(), page.getRecords()); } + /** + * @param + * @return cn.zyjblogs.starter.common.entity.response.ResponseObject> + * @author zhuyijun + * @date 2022/9/22 下午11:33 + */ + @ApiOperation(value = "", notes = "查询所有角色") + @GetMapping("/list") + public ResponseObject> findList() { + return ResponseResult.success(roleService.findList()); + } + /** * 通过id集合查询 * @@ -63,6 +80,7 @@ public class RoleController { * @author zhuyijun * @date 2022/9/19 上午1:14 */ + @ApiOperation(value = "1", notes = "通过角色id查询") @PostMapping("/findByIds") public ResponseObject> findByIds(List ids) { return ResponseResult.success(roleService.findByIds(ids)); diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/dto/RolePageDto.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/dto/RolePageDto.java index e4b47ec..e618717 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/dto/RolePageDto.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/dto/RolePageDto.java @@ -1,7 +1,13 @@ package cn.zyjblogs.server.role.dto; +import cn.zyjblogs.starter.common.entity.constant.CommonConstant; import cn.zyjblogs.starter.common.entity.dto.PageDto; import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -28,12 +34,18 @@ public class RolePageDto extends PageDto implements Serializable { private String createUserId; - @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JSONField(format = CommonConstant.DATETIME_PATTERN) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = CommonConstant.DATETIME_PATTERN) private LocalDateTime createTime; private String editUserId; - @JSONField(format = "yyyy-MM-dd HH:mm:ss") + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JSONField(format = CommonConstant.DATETIME_PATTERN) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = CommonConstant.DATETIME_PATTERN) private LocalDateTime editTime; private String tenantId; diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/po/RolePo.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/po/RolePo.java index a27ff7f..00a6ea5 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/po/RolePo.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/po/RolePo.java @@ -1,11 +1,12 @@ package cn.zyjblogs.server.role.po; -import com.alibaba.fastjson.annotation.JSONField; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import lombok.AllArgsConstructor; import lombok.Builder; @@ -40,6 +41,7 @@ public class RolePo implements Serializable { private String createUserId; @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @TableField("create_time") private LocalDateTime createTime; @@ -48,9 +50,11 @@ public class RolePo implements Serializable { private String editUserId; @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @TableField("edit_time") private LocalDateTime editTime; + @TableField("tenant_id") private String tenantId; diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/service/RoleService.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/service/RoleService.java index 4344004..b4aa331 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/service/RoleService.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/service/RoleService.java @@ -29,4 +29,12 @@ public interface RoleService extends IService { * @date 2022/9/19 下午6:34 */ List findByIds(List ids); + + /** + * 查询当前租户下所有角色 + * + * @return + */ + List findList(); + } diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/service/impl/RoleServiceImpl.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/service/impl/RoleServiceImpl.java index 14636bc..45fc2f3 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/service/impl/RoleServiceImpl.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/role/service/impl/RoleServiceImpl.java @@ -7,13 +7,16 @@ import cn.zyjblogs.server.role.service.RoleService; import cn.zyjblogs.server.role.vo.RoleVo; import cn.zyjblogs.starter.common.entity.context.BaseContext; import cn.zyjblogs.starter.common.utils.bean.BeanUtils; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -55,4 +58,23 @@ public class RoleServiceImpl extends ServiceImpl implements } return BeanUtils.map(rolePos, RoleVo.class); } + + /** + * 查询当前租户下所有角色 + * + * @param + * @return java.util.List + * @author zhuyijun + * @date 2022/9/22 下午11:32 + */ + @Override + public List findList() { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(RolePo::getTenantId, BaseContext.getTenantId()); + List rolePos = roleMapper.selectList(wrapper); + if (CollectionUtils.isEmpty(rolePos)) { + return new ArrayList<>(); + } + return BeanUtils.map(rolePos, RoleVo.class); + } } diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/controller/UserController.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/controller/UserController.java index 30fdfbf..07e8c6c 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/controller/UserController.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/controller/UserController.java @@ -1,5 +1,6 @@ package cn.zyjblogs.server.user.controller; +import cn.zyjblogs.server.user.dto.UserDto; import cn.zyjblogs.server.user.dto.UserPageDto; import cn.zyjblogs.server.user.po.UserPo; import cn.zyjblogs.server.user.service.UserService; @@ -7,10 +8,15 @@ import cn.zyjblogs.server.user.vo.UserVo; import cn.zyjblogs.starter.common.entity.response.ResponseObject; import cn.zyjblogs.starter.common.entity.response.ResponseResult; import com.baomidou.mybatisplus.core.metadata.IPage; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @@ -21,6 +27,7 @@ import java.util.List; /** * @author zhuyijun */ +@Api(tags = {"用户管理"}) @RestController @RequestMapping("/user") @RequiredArgsConstructor @@ -38,6 +45,7 @@ public class UserController { * @author zhuyijun * @date 2022/9/19 上午12:06 */ + @ApiOperation(value = "", notes = "通过id查询用户") @GetMapping("/id") public ResponseObject findById(@RequestParam String id) { return ResponseResult.success(userService.getById(id)); @@ -50,6 +58,7 @@ public class UserController { * @author zhuyijun * @date 2022/9/19 上午1:14 */ + @ApiOperation(value = "", notes = "分页查询") @GetMapping("/page") public ResponseObject> findPage(UserPageDto userPageDto) { IPage page = userService.findPage(userPageDto); @@ -64,8 +73,15 @@ public class UserController { * @author zhuyijun * @date 2022/9/19 上午1:14 */ + @ApiOperation(value = "", notes = "通过id集合查询用户") @PostMapping("/findByIds") public ResponseObject> findByIds(List ids) { return ResponseResult.success(userService.findByIds(ids)); } + + @ApiOperation(value = "", notes = "用户保存") + @PutMapping("/saveUser") + public ResponseObject saveUser(@RequestBody @Validated UserDto userDto) { + return userService.saveUser(userDto); + } } diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/dto/UserDto.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/dto/UserDto.java new file mode 100644 index 0000000..6e3b1bc --- /dev/null +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/dto/UserDto.java @@ -0,0 +1,72 @@ +package cn.zyjblogs.server.user.dto; + +import cn.zyjblogs.starter.common.entity.constant.CommonConstant; +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import java.time.LocalDateTime; + +/** + * @author zhuyijun + */ +@ApiModel(description = "用户Dto") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class UserDto { + private String id; + + @NotBlank(message = "账号不能为空") + private String username; + + private String name; + + private Integer age; + + private String avatar; + + private String phone; + + private String email; + + private String inviteUserId; + + private Integer status; + + private Integer followNum; + + private Integer fansNum; + + private Integer deleted; + + private String description; + + private String createUserId; + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JSONField(format = CommonConstant.DATETIME_PATTERN) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = CommonConstant.DATETIME_PATTERN) + private LocalDateTime createTime; + + private String editUserId; + + + @JSONField(format = CommonConstant.DATETIME_PATTERN) + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = CommonConstant.DATETIME_PATTERN) + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + private LocalDateTime editTime; + + private String tenantId; +} diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/mapper/UserMapper.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/mapper/UserMapper.java index 0b7910f..fdec3d1 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/mapper/UserMapper.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/mapper/UserMapper.java @@ -1,5 +1,6 @@ package cn.zyjblogs.server.user.mapper; +import cn.zyjblogs.server.user.dto.UserDto; import cn.zyjblogs.server.user.dto.UserPageDto; import cn.zyjblogs.server.user.po.UserPo; import cn.zyjblogs.server.user.vo.UserVo; @@ -31,4 +32,12 @@ public interface UserMapper extends BaseMapper { * @date 2022/9/19 上午12:47 */ IPage findPage(IPage page, @Param("userPageDto") UserPageDto userPageDto, @Param("tenantId") String tenantId); + + /** + * @param userDto + * @return java.lang.Integer + * @author zhuyijun + * @date 2022/9/22 下午6:11 + */ + Integer checkUserCount(@Param("userDto") UserDto userDto); } diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/po/UserPo.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/po/UserPo.java index 357bacd..44a7f3d 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/po/UserPo.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/po/UserPo.java @@ -1,12 +1,13 @@ package cn.zyjblogs.server.user.po; -import com.alibaba.fastjson.annotation.JSONField; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import lombok.AllArgsConstructor; import lombok.Builder; @@ -14,7 +15,6 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; -import java.sql.Timestamp; import java.time.LocalDateTime; /** @@ -73,6 +73,7 @@ public class UserPo implements Serializable { private String createUserId; @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @TableField("create_time") private LocalDateTime createTime; @@ -80,8 +81,8 @@ public class UserPo implements Serializable { @TableField("edit_user_id") private String editUserId; - @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @TableField("edit_time") private LocalDateTime editTime; diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/service/UserService.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/service/UserService.java index 046d942..8ac15e0 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/service/UserService.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/service/UserService.java @@ -1,10 +1,13 @@ package cn.zyjblogs.server.user.service; +import cn.zyjblogs.server.user.dto.UserDto; import cn.zyjblogs.server.user.dto.UserPageDto; import cn.zyjblogs.server.user.po.UserPo; import cn.zyjblogs.server.user.vo.UserVo; +import cn.zyjblogs.starter.common.entity.response.ResponseObject; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; +import org.springframework.web.bind.annotation.RequestBody; import java.util.List; @@ -30,4 +33,12 @@ public interface UserService extends IService { */ List findByIds(List ids); + /** + * @param userDto + * @return java.lang.String + * @author zhuyijun + * @date 2022/9/22 下午5:34 + */ + ResponseObject saveUser(@RequestBody UserDto userDto); + } diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/service/impl/UserServiceImpl.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/service/impl/UserServiceImpl.java index c453407..d353faa 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/service/impl/UserServiceImpl.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/service/impl/UserServiceImpl.java @@ -1,12 +1,16 @@ package cn.zyjblogs.server.user.service.impl; +import cn.zyjblogs.server.user.dto.UserDto; import cn.zyjblogs.server.user.dto.UserPageDto; import cn.zyjblogs.server.user.mapper.UserMapper; import cn.zyjblogs.server.user.po.UserPo; import cn.zyjblogs.server.user.service.UserService; import cn.zyjblogs.server.user.vo.UserVo; import cn.zyjblogs.starter.common.entity.context.BaseContext; +import cn.zyjblogs.starter.common.entity.response.HttpCode; +import cn.zyjblogs.starter.common.entity.response.ResponseObject; +import cn.zyjblogs.starter.common.entity.response.ResponseResult; import cn.zyjblogs.starter.common.utils.bean.BeanUtils; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -56,4 +60,33 @@ public class UserServiceImpl extends ServiceImpl implements } return BeanUtils.map(userPos, UserVo.class); } + + /** + * @param userDto + * @return java.lang.Boolean + * @author zhuyijun + * @date 2022/9/22 下午6:04 + */ + @Override + public ResponseObject saveUser(UserDto userDto) { + if (checkUser(userDto)) { + return ResponseResult.error(HttpCode.BAD_REQUEST, "该账号已存在"); + } + UserPo userPo = BeanUtils.map(userDto, UserPo.class); + int count = userMapper.insert(userPo); + if (count > 0) { + return ResponseResult.success("用户创建成功"); + } + return ResponseResult.error(HttpCode.BAD_REQUEST, "用户创建是失败"); + } + + /** + * 校验用户是否存在 + * + * @param userDto + * @return + */ + public boolean checkUser(UserDto userDto) { + return userMapper.checkUserCount(userDto) > 0; + } } diff --git a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/vo/UserVo.java b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/vo/UserVo.java index aa5f476..2971a8f 100644 --- a/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/vo/UserVo.java +++ b/server/zyjblogs-rbac/src/main/java/cn/zyjblogs/server/user/vo/UserVo.java @@ -1,7 +1,7 @@ package cn.zyjblogs.server.user.vo; +import cn.zyjblogs.starter.common.entity.constant.CommonConstant; import com.alibaba.fastjson.annotation.JSONField; -import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import lombok.AllArgsConstructor; @@ -10,7 +10,6 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; -import java.sql.Timestamp; import java.time.LocalDateTime; /** @@ -51,14 +50,14 @@ public class UserVo implements Serializable { private String createUserId; @JsonSerialize(using = LocalDateTimeSerializer.class) - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JSONField(format = CommonConstant.DATETIME_PATTERN) private LocalDateTime createTime; private String editUserId; @JsonSerialize(using = LocalDateTimeSerializer.class) - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JSONField(format = CommonConstant.DATETIME_PATTERN) private LocalDateTime editTime; private String tenantId; diff --git a/server/zyjblogs-rbac/src/main/resources/bootstrap.yml b/server/zyjblogs-rbac/src/main/resources/bootstrap.yml index 4c00875..7873535 100644 --- a/server/zyjblogs-rbac/src/main/resources/bootstrap.yml +++ b/server/zyjblogs-rbac/src/main/resources/bootstrap.yml @@ -3,7 +3,10 @@ spring: active: test --- + spring: + main: + allow-bean-definition-overriding: true application: name: zyjblogs-rbac cloud: @@ -18,6 +21,7 @@ spring: shared-configs[0]: data-id: zyjblogs-global-${spring.profiles.active}.yml group: global + refresh: true discovery: server-addr: ${spring.cloud.nacos.config.server-addr} username: ${spring.cloud.nacos.config.username} @@ -32,21 +36,4 @@ security: oauth2: client: client-id: ${spring.application.name} - client-secret: secret -# 配置了公钥和私钥的位置 -rsa: - key: - enable: true - pubKeyPath: public.txt - priKeyPath: private.txt - -#security: -# oauth2: -# client: -# client-id: ${spring.application.name} -# client-secret: secret -# access-token-uri: http://localhost:9029/oauth/token -# grant-type: client_credentials -# scope: write read -# authorization: -# check-token-access: http://localhost:9029/oauth/check_token \ No newline at end of file + client-secret: secret \ No newline at end of file diff --git a/server/zyjblogs-rbac/src/main/resources/mapper/mysql/user/UserMapper.xml b/server/zyjblogs-rbac/src/main/resources/mapper/mysql/user/UserMapper.xml index 72223e1..b62c684 100644 --- a/server/zyjblogs-rbac/src/main/resources/mapper/mysql/user/UserMapper.xml +++ b/server/zyjblogs-rbac/src/main/resources/mapper/mysql/user/UserMapper.xml @@ -1,8 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + id,username,name,age,avatar,phone, + email,invite_user_id,status,follow_num, + fans_num,deleted,description,create_user_id, + create_time,edit_user_id,edit_time,tenant_id + - + \ No newline at end of file diff --git a/server/zyjblogs-rbac/src/main/resources/mapper/postgresql/user/UserMapper.xml b/server/zyjblogs-rbac/src/main/resources/mapper/postgresql/user/UserMapper.xml index 72223e1..2a52b75 100644 --- a/server/zyjblogs-rbac/src/main/resources/mapper/postgresql/user/UserMapper.xml +++ b/server/zyjblogs-rbac/src/main/resources/mapper/postgresql/user/UserMapper.xml @@ -11,19 +11,21 @@ - + \ No newline at end of file diff --git a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/entity/response/ResponseObject.java b/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/entity/response/ResponseObject.java index 3802d44..f4cab5d 100644 --- a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/entity/response/ResponseObject.java +++ b/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/entity/response/ResponseObject.java @@ -13,7 +13,7 @@ import lombok.Data; import lombok.NoArgsConstructor; @ApiModel( - description = "状态返回信息" + description = "状态返回信息" ) @Data @AllArgsConstructor @@ -21,30 +21,25 @@ import lombok.NoArgsConstructor; @Builder public class ResponseObject { @ApiModelProperty( - value = "响应结果编码", - example = "200" + value = "响应结果编码", + example = "200" ) private int code; @ApiModelProperty( - value = "错误码", - example = "user_not_exists" - ) - private String errorCode; - @ApiModelProperty( - value = "响应结果信息", - example = "请求成功" + value = "响应结果信息", + example = "请求成功" ) private String msg; @ApiModelProperty( - value = "统计列表总数(如果列表存在)", - example = "10" + value = "统计列表总数(如果列表存在)", + example = "10" ) private long count; @ApiModelProperty("响应结果数据") private T data; @ApiModelProperty( - value = "当前时间戳", - example = "1630051102895" + value = "当前时间戳", + example = "1630051102895" ) private long timestamp; } diff --git a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/jwt/JwtParsers.java b/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/jwt/JwtParsers.java index 2ba5d4f..ffb1d47 100644 --- a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/jwt/JwtParsers.java +++ b/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/jwt/JwtParsers.java @@ -1,6 +1,20 @@ package cn.zyjblogs.starter.common.utils.jwt; -import io.jsonwebtoken.*; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Clock; +import io.jsonwebtoken.CompressionCodec; +import io.jsonwebtoken.CompressionCodecResolver; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Header; +import io.jsonwebtoken.JwsHeader; +import io.jsonwebtoken.Jwt; +import io.jsonwebtoken.JwtParser; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.PrematureJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.SignatureException; +import io.jsonwebtoken.SigningKeyResolver; +import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.impl.DefaultClaims; import io.jsonwebtoken.impl.DefaultClock; import io.jsonwebtoken.impl.DefaultHeader; @@ -21,8 +35,9 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; - /** + * jwt解析 + * * @author zhuyijun */ public class JwtParsers extends DefaultJwtParser { diff --git a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/rsa/RsaUtils.java b/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/rsa/RsaUtils.java index f921e09..4156c31 100644 --- a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/rsa/RsaUtils.java +++ b/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/rsa/RsaUtils.java @@ -1,25 +1,37 @@ package cn.zyjblogs.starter.common.utils.rsa; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; import javax.crypto.Cipher; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.security.*; +import java.nio.file.Paths; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; -import java.util.stream.Collectors; +/** + * Copyright (C), 2021, 北京同创永益科技发展有限公司 + * + * @author meiji + * @version 3.0.0 + * @description RsaUtils + * @date 2021/11/4 9:18 + */ +@Slf4j +public final class RsaUtils { -public class RsaUtils { private static final String DEFAULT_ALGORITHM = "RSA"; - private static final Logger log = LoggerFactory.getLogger(RsaUtils.class); private RsaUtils() { } @@ -86,7 +98,6 @@ public class RsaUtils { * @param rawStr * @param privateKey * @return java.lang.String - * @author meiji * @date 2021/11/4 9:43 */ public static String privateKeyEncrypt(String rawStr, String privateKey) throws Exception { @@ -103,7 +114,6 @@ public class RsaUtils { * @param encodeStr * @param privateKey * @return java.lang.String - * @author meiji * @date 2021/11/4 9:43 */ public static String privateKeyDecrypt(String encodeStr, String privateKey) throws Exception { @@ -119,29 +129,25 @@ public class RsaUtils { * * @param path 公钥路径 * @return 公钥 - * @author tanyuanzhi * @date 2021/11/9 10:06 */ public static PublicKey getPublicKeyByPath(String path) { - InputStream inputStream = RsaUtils.class.getClassLoader().getResourceAsStream(path); - if (inputStream == null) { - log.error("获取公钥出错,找不到公钥文件"); - return null; - } - String publicKeyStr = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining()); - publicKeyStr = publicKeyStr.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", ""); - byte[] keyBytes = Base64.getMimeDecoder().decode(publicKeyStr); - // 通过X509编码的Key指令获得公钥对象 - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); try { + String key = IOUtils.toString(Paths.get(path).toUri(), StandardCharsets.UTF_8); + key = key.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", ""); + byte[] keyBytes = Base64.getMimeDecoder().decode(key); + // 通过X509编码的Key指令获得公钥对象 + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(DEFAULT_ALGORITHM); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; - } catch (Exception e) { + } catch (IOException | InvalidKeySpecException e) { log.error("获取公钥出错", e); return null; + } catch (NoSuchAlgorithmException e) { + log.error("不支持此算法", e); + return null; } } } - diff --git a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/web/RequestUtils.java b/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/web/RequestUtils.java deleted file mode 100644 index 9c947b1..0000000 --- a/stater/zyjblogs-common-spring-boot-starter/src/main/java/cn/zyjblogs/starter/common/utils/web/RequestUtils.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.zyjblogs.starter.common.utils.web; - -import cn.zyjblogs.starter.common.entity.constant.HttpHeaderConstant; -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; - -public class RequestUtils { - - private RequestUtils() { - - } - - /** - * 请求是否来自网关 - * - * @param request 请求信息 - * @return boolean - * @date 2022/3/3 14:19 - */ - public static boolean requestFromGateway(HttpServletRequest request) { - return StringUtils.isNotEmpty(request.getHeader(HttpHeaderConstant.REQUEST_FROM_GATEWAY_KEY)); - } - - /** - * 请求是否来自feign调用 - * - * @param request 请求信息 - * @return boolean - * @date 2022/3/3 14:19 - */ - public static boolean requestFromFeign(HttpServletRequest request) { - return StringUtils.isNotEmpty(request.getHeader(HttpHeaderConstant.REQUEST_FROM_FEIGN_KEY)); - } -} diff --git a/stater/zyjblogs-mybatisplus-spring-boot-starter/pom.xml b/stater/zyjblogs-mybatisplus-spring-boot-starter/pom.xml index f63e452..a94df44 100644 --- a/stater/zyjblogs-mybatisplus-spring-boot-starter/pom.xml +++ b/stater/zyjblogs-mybatisplus-spring-boot-starter/pom.xml @@ -46,6 +46,20 @@ org.postgresql postgresql + + org.apache.shardingsphere + sharding-jdbc-spring-boot-starter + + + org.springframework.boot + spring-boot-actuator-autoconfigure + + + org.mybatis + mybatis-typehandlers-jsr310 + 1.0.2 + + diff --git a/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/java/cn/zyjblogs/starter/mybatisplus/autoconfigure/CustomLocalDateTimeTypeHandler.java b/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/java/cn/zyjblogs/starter/mybatisplus/autoconfigure/CustomLocalDateTimeTypeHandler.java new file mode 100644 index 0000000..2647758 --- /dev/null +++ b/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/java/cn/zyjblogs/starter/mybatisplus/autoconfigure/CustomLocalDateTimeTypeHandler.java @@ -0,0 +1,63 @@ +package cn.zyjblogs.starter.mybatisplus.autoconfigure; + +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.MappedJdbcTypes; +import org.apache.ibatis.type.MappedTypes; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 定义转换器支持的JAVA类型 + * 定义转换器支持的数据库类型 + * + * @author zhuyijun + */ +@Component +@MappedTypes(LocalDateTime.class) +@MappedJdbcTypes(value = JdbcType.TIMESTAMP, includeNullJdbcType = true) +public class CustomLocalDateTimeTypeHandler extends BaseTypeHandler { + private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType) + throws SQLException { + if (parameter != null) { + ps.setString(i, dateTimeFormatter.format(parameter)); + } + } + + @Override + public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException { + String target = rs.getString(columnName); + if (StringUtils.isEmpty(target)) { + return null; + } + return LocalDateTime.parse(target, dateTimeFormatter); + } + + @Override + public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + String target = rs.getString(columnIndex); + if (StringUtils.isEmpty(target)) { + return null; + } + return LocalDateTime.parse(target, dateTimeFormatter); + } + + @Override + public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + String target = cs.getString(columnIndex); + if (StringUtils.isEmpty(target)) { + return null; + } + return LocalDateTime.parse(target, dateTimeFormatter); + } +} diff --git a/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/java/cn/zyjblogs/starter/mybatisplus/autoconfigure/DataSourceHealthConfig.java b/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/java/cn/zyjblogs/starter/mybatisplus/autoconfigure/DataSourceHealthConfig.java new file mode 100644 index 0000000..a02aaa7 --- /dev/null +++ b/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/java/cn/zyjblogs/starter/mybatisplus/autoconfigure/DataSourceHealthConfig.java @@ -0,0 +1,37 @@ +package cn.zyjblogs.starter.mybatisplus.autoconfigure; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthContributorAutoConfiguration; +import org.springframework.boot.actuate.health.AbstractHealthIndicator; +import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator; +import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + +import javax.sql.DataSource; +import java.util.Map; + +/** + * @author zhuyijun + */ +@Configuration +public class DataSourceHealthConfig extends DataSourceHealthContributorAutoConfiguration { + + @Value("${spring.datasource.dbcp2.validation-query:select 1}") + private String defaultQuery; + + public DataSourceHealthConfig(Map dataSources, ObjectProvider metadataProviders) { + super(dataSources, metadataProviders); + } + + @Override + protected AbstractHealthIndicator createIndicator(DataSource source) { + DataSourceHealthIndicator indicator = (DataSourceHealthIndicator) super.createIndicator(source); + if (!StringUtils.hasText(indicator.getQuery())) { + indicator.setQuery(defaultQuery); + } + return indicator; + } + +} diff --git a/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/resources/META-INF/spring.factories b/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/resources/META-INF/spring.factories index be86ee4..92de1c4 100644 --- a/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/stater/zyjblogs-mybatisplus-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -1,2 +1,4 @@ org.springframework.boot.cn.zyjblogs.starter.feign.autoconfigure.EnableAutoConfiguration=\ - cn.zyjblogs.starter.mybatisplus.autoconfigure.MyBatisPlusConfig + cn.zyjblogs.starter.mybatisplus.autoconfigure.MyBatisPlusConfig,\ + cn.zyjblogs.starter.mybatisplus.autoconfigure.DataSourceHealthConfig,\ + cn.zyjblogs.starter.mybatisplus.autoconfigure.CustomLocalDateTimeTypeHandler \ No newline at end of file diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/OauthAutoConfiguration.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/OauthAutoConfiguration.java index f59b03c..8a943e5 100644 --- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/OauthAutoConfiguration.java +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/OauthAutoConfiguration.java @@ -7,6 +7,6 @@ import org.springframework.context.annotation.Configuration; * @author zhuyijun */ @Configuration -@EnableConfigurationProperties(RsaKeyProperties.class) +@EnableConfigurationProperties({RsaKeyProperties.class, WhiteListProperties.class}) public class OauthAutoConfiguration { } diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/RsaKeyProperties.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/RsaKeyProperties.java index 799e854..8fd07e3 100644 --- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/RsaKeyProperties.java +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/RsaKeyProperties.java @@ -4,6 +4,7 @@ package cn.zyjblogs.starter.oauth.autoconfigure; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; /** * rsa 路径配置文件 @@ -13,6 +14,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @Getter @Setter @ConfigurationProperties(prefix = "rsa.key") +@RefreshScope public class RsaKeyProperties { /** * 启用rsa对token进行加密 diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/WhiteListProperties.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/WhiteListProperties.java new file mode 100644 index 0000000..9dac4ce --- /dev/null +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/autoconfigure/WhiteListProperties.java @@ -0,0 +1,20 @@ +package cn.zyjblogs.starter.oauth.autoconfigure; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; + +import java.util.List; + +/** + * 白名单 + * + * @author zhuyijun + */ +@Data +@RefreshScope +@ConfigurationProperties(prefix = "zyjblogs.whilelist") +public class WhiteListProperties { + + private List allowPaths; +} diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/config/JwtTokenHandlerInterceptor.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/interceptor/JwtTokenHandlerInterceptor.java similarity index 86% rename from stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/config/JwtTokenHandlerInterceptor.java rename to stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/interceptor/JwtTokenHandlerInterceptor.java index 6317752..2de4904 100644 --- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/config/JwtTokenHandlerInterceptor.java +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/interceptor/JwtTokenHandlerInterceptor.java @@ -1,4 +1,4 @@ -package cn.zyjblogs.starter.oauth.config; +package cn.zyjblogs.starter.oauth.interceptor; import cn.zyjblogs.starter.common.entity.constant.HttpHeaderConstant; import cn.zyjblogs.starter.common.entity.context.BaseContext; @@ -10,10 +10,13 @@ import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +/** + * @author zhuyijun + */ @Slf4j public class JwtTokenHandlerInterceptor extends HandlerInterceptorAdapter { - private boolean checkInner; + private final boolean checkInner; public JwtTokenHandlerInterceptor(boolean checkInner) { this.checkInner = checkInner; @@ -22,6 +25,9 @@ public class JwtTokenHandlerInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String authorization = request.getHeader(HttpHeaderConstant.AUTHORIZATION); + if (!checkInner) { + return true; + } //token为空直接放行 if (StringUtils.isEmpty(authorization)) { BaseContext.set(ContextDto.builder().build()); diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/config/OauthFeignInterceptorAutoConfiguration.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/interceptor/OauthFeignInterceptorAutoConfiguration.java similarity index 87% rename from stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/config/OauthFeignInterceptorAutoConfiguration.java rename to stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/interceptor/OauthFeignInterceptorAutoConfiguration.java index 706e30d..2929616 100644 --- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/config/OauthFeignInterceptorAutoConfiguration.java +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/interceptor/OauthFeignInterceptorAutoConfiguration.java @@ -1,4 +1,4 @@ -package cn.zyjblogs.starter.oauth.config; +package cn.zyjblogs.starter.oauth.interceptor; import cn.zyjblogs.starter.common.entity.constant.HttpHeaderConstant; import cn.zyjblogs.starter.common.entity.context.BaseContext; @@ -29,12 +29,13 @@ public class OauthFeignInterceptorAutoConfiguration { /** * token信息补全,token不能为空 + * + * @return 补全后得token * @author liuweicheng * @date 2022/03/12 - * @return 补全后得token */ - private String tokenCompletion(String token){ - if(token.indexOf(HttpHeaderConstant.AUTHORIZATION_TYPE) != 0){ + private String tokenCompletion(String token) { + if (token.indexOf(HttpHeaderConstant.AUTHORIZATION_TYPE) != 0) { token = HttpHeaderConstant.AUTHORIZATION_TYPE + " " + token; } return token; diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/config/OauthInterceptorAutoConfiguration.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/interceptor/OauthInterceptorAutoConfiguration.java similarity index 97% rename from stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/config/OauthInterceptorAutoConfiguration.java rename to stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/interceptor/OauthInterceptorAutoConfiguration.java index a53b30b..0962987 100644 --- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/config/OauthInterceptorAutoConfiguration.java +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/interceptor/OauthInterceptorAutoConfiguration.java @@ -1,4 +1,4 @@ -package cn.zyjblogs.starter.oauth.config; +package cn.zyjblogs.starter.oauth.interceptor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/resource/ResourceServerConfig.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/resource/ResourceServerConfig.java index 54b7b7f..ba66f5d 100644 --- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/resource/ResourceServerConfig.java +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/resource/ResourceServerConfig.java @@ -1,5 +1,6 @@ package cn.zyjblogs.starter.oauth.resource; +import cn.zyjblogs.starter.oauth.autoconfigure.WhiteListProperties; import cn.zyjblogs.starter.oauth.handler.ResourceAccessDeniedHandler; import cn.zyjblogs.starter.oauth.handler.ResourceAuthenticationEntryPoint; import lombok.RequiredArgsConstructor; @@ -26,6 +27,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Value("${spring.application.name}") private String resourceId; private final TokenStore tokenStore; + private final WhiteListProperties whiteListProperties; @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { @@ -41,6 +43,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter { public void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() + .antMatchers("/webjars/**", "/swagger-ui.html/**", "/swagger-resources/**", "/v2/api-docs/**", String.join(",", whiteListProperties.getAllowPaths())).permitAll() .anyRequest() .authenticated() .and() diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/security/OauthAccessTokenConverter.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/token/OauthAccessTokenConverter.java similarity index 97% rename from stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/security/OauthAccessTokenConverter.java rename to stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/token/OauthAccessTokenConverter.java index dfc6466..cf5ccb3 100644 --- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/security/OauthAccessTokenConverter.java +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/token/OauthAccessTokenConverter.java @@ -1,4 +1,4 @@ -package cn.zyjblogs.starter.oauth.security; +package cn.zyjblogs.starter.oauth.token; import cn.zyjblogs.starter.common.entity.constant.ContextKeyConstant; import cn.zyjblogs.starter.common.entity.context.BaseContext; diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/security/TokenConfig.java b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/token/TokenConfig.java similarity index 85% rename from stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/security/TokenConfig.java rename to stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/token/TokenConfig.java index 55610a7..813c99c 100644 --- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/security/TokenConfig.java +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/java/cn/zyjblogs/starter/oauth/token/TokenConfig.java @@ -1,10 +1,12 @@ -package cn.zyjblogs.starter.oauth.security; +package cn.zyjblogs.starter.oauth.token; import cn.zyjblogs.starter.oauth.autoconfigure.RsaKeyProperties; import lombok.RequiredArgsConstructor; import org.apache.commons.io.IOUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; @@ -23,6 +25,11 @@ public class TokenConfig { private final RsaKeyProperties rsaKeyProperties; private final OauthAccessTokenConverter oauthAccessTokenConverter; + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + /** * 令牌存储策略 * diff --git a/stater/zyjblogs-oauth-spring-boot-starter/src/main/resources/META-INF/spring.factories b/stater/zyjblogs-oauth-spring-boot-starter/src/main/resources/META-INF/spring.factories index 237480e..a00b35c 100644 --- a/stater/zyjblogs-oauth-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/stater/zyjblogs-oauth-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -1,7 +1,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - cn.zyjblogs.starter.oauth.config.OauthFeignInterceptorAutoConfiguration,\ + cn.zyjblogs.starter.oauth.interceptor.OauthFeignInterceptorAutoConfiguration,\ cn.zyjblogs.starter.oauth.resource.ResourceServerConfig,\ - cn.zyjblogs.starter.oauth.security.TokenConfig,\ - cn.zyjblogs.starter.oauth.security.OauthAccessTokenConverter,\ - cn.zyjblogs.starter.oauth.config.OauthInterceptorAutoConfiguration,\ + cn.zyjblogs.starter.oauth.token.TokenConfig,\ + cn.zyjblogs.starter.oauth.token.OauthAccessTokenConverter,\ + cn.zyjblogs.starter.oauth.interceptor.OauthInterceptorAutoConfiguration,\ cn.zyjblogs.starter.oauth.autoconfigure.OauthAutoConfiguration \ No newline at end of file diff --git a/stater/zyjblogs-web-spring-boot-starter/pom.xml b/stater/zyjblogs-web-spring-boot-starter/pom.xml index 0b4c4bb..3129c1c 100644 --- a/stater/zyjblogs-web-spring-boot-starter/pom.xml +++ b/stater/zyjblogs-web-spring-boot-starter/pom.xml @@ -45,6 +45,12 @@ org.springframework spring-jdbc + + + com.github.xiaoymin + knife4j-spring-boot-starter + + diff --git a/stater/zyjblogs-web-spring-boot-starter/src/main/java/cn/zyjblogs/starter/web/autoconfig/Knife4jAutoConfigurationConfig.java b/stater/zyjblogs-web-spring-boot-starter/src/main/java/cn/zyjblogs/starter/web/autoconfig/Knife4jAutoConfigurationConfig.java new file mode 100644 index 0000000..2f69274 --- /dev/null +++ b/stater/zyjblogs-web-spring-boot-starter/src/main/java/cn/zyjblogs/starter/web/autoconfig/Knife4jAutoConfigurationConfig.java @@ -0,0 +1,145 @@ +package cn.zyjblogs.starter.web.autoconfig; + +import com.google.common.collect.Lists; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; +import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.oas.annotations.EnableOpenApi; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.Contact; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.service.SecurityScheme; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider; +import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; + +import java.lang.reflect.Field; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZonedDateTime; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + + +@EnableOpenApi +@Configuration +@Import(BeanValidatorPluginsConfiguration.class) +public class Knife4jAutoConfigurationConfig { + + @Value("${spring.application.name}") + private String applicationName; + +// @Bean +// public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() { +// return new BeanPostProcessor() { +// +// @Override +// public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { +// if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { +// customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); +// } +// return bean; +// } +// +// private void customizeSpringfoxHandlerMappings(List mappings) { +// List copy = mappings.stream() +// .filter(mapping -> mapping.getPatternParser() == null) +// .collect(Collectors.toList()); +// mappings.clear(); +// mappings.addAll(copy); +// } +// +// @SuppressWarnings("unchecked") +// private List getHandlerMappings(Object bean) { +// try { +// Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); +// field.setAccessible(true); +// return (List) field.get(bean); +// } catch (IllegalArgumentException | IllegalAccessException e) { +// throw new IllegalStateException(e); +// } +// } +// }; +// } + + @Bean(value = "defaultApi") + public Docket defaultApi() { + return new Docket(DocumentationType.SWAGGER_2) + .directModelSubstitute(LocalDateTime.class, Date.class) + .directModelSubstitute(LocalDate.class, String.class) + .directModelSubstitute(LocalTime.class, String.class) + .directModelSubstitute(ZonedDateTime.class, String.class) + .apiInfo(apiInfo()) + .select() + //controller层包路径 + .apis(RequestHandlerSelectors.basePackage("cn.zyjblogs.server")) + .paths(PathSelectors.any()) + .build() + .securityContexts(Lists.newArrayList(securityContext(), securityContext())).securitySchemes(Lists.newArrayList(apiKey())); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title(applicationName.toUpperCase() + " RESTFUL APIS") + .contact(new Contact("zyjblogs", "", "")) + .version("1.0.0") + .build(); + } + + /** + * token头key + * + * @param + * @return ApiKey + * @author liuweicheng + * @date 2021/11/4 11:29 + */ + private ApiKey apiKey() { + return new ApiKey("BearerToken", "Authorization", "header"); + } + + /** + * token定义 + * + * @param + * @return SecurityContext + * @author liuweicheng + * @date 2021/11/4 11:28 + */ + private SecurityContext securityContext() { + return SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex("/.*")) + .build(); + } + + /** + * token描述定义 + * + * @param + * @return java.util.List + * @author zhuyijun + * @date 2022/9/23 上午12:20 + */ + private List defaultAuth() { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + return Lists.newArrayList(new SecurityReference("BearerToken", authorizationScopes)); + } +} diff --git a/stater/zyjblogs-web-spring-boot-starter/src/main/resources/META-INF/spring.factories b/stater/zyjblogs-web-spring-boot-starter/src/main/resources/META-INF/spring.factories index ed3a26f..221ae97 100644 --- a/stater/zyjblogs-web-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/stater/zyjblogs-web-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -1,3 +1,4 @@ ## Auto Configure org.springframework.boot.cn.zyjblogs.starter.feign.autoconfigure.EnableAutoConfiguration=\ - cn.zyjblogs.starter.web.autoconfig.GlobalExceptionHandlerAutoConfiguration + cn.zyjblogs.starter.web.autoconfig.GlobalExceptionHandlerAutoConfiguration,\ + cn.zyjblogs.starter.web.autoconfig.Knife4jAutoConfigurationConfig