فهرست منبع

:tada: 优化token发放逻辑,增加其可拓展性

smallchill 7 سال پیش
والد
کامیت
f74e694473
22فایلهای تغییر یافته به همراه532 افزوده شده و 117 حذف شده
  1. 78 0
      doc/sql/bladex-datascope-update.sql
  2. 0 26
      doc/sql/bladex-tenantid-update.sql
  3. 3 3
      pom.xml
  4. 81 0
      src/main/java/org/springblade/modules/auth/controller/AuthController.java
  5. 45 0
      src/main/java/org/springblade/modules/auth/enums/BladeUserEnum.java
  6. 38 0
      src/main/java/org/springblade/modules/auth/granter/ITokenGranter.java
  7. 59 0
      src/main/java/org/springblade/modules/auth/granter/PasswordTokenGranter.java
  8. 53 0
      src/main/java/org/springblade/modules/auth/granter/RefreshTokenGranter.java
  9. 52 0
      src/main/java/org/springblade/modules/auth/granter/TokenGranterBuilder.java
  10. 32 0
      src/main/java/org/springblade/modules/auth/granter/TokenParameter.java
  11. 45 65
      src/main/java/org/springblade/modules/auth/utils/TokenUtil.java
  12. 2 1
      src/main/java/org/springblade/modules/desk/mapper/NoticeMapper.java
  13. 28 14
      src/main/java/org/springblade/modules/desk/mapper/NoticeMapper.xml
  14. 2 1
      src/main/java/org/springblade/modules/desk/service/INoticeService.java
  15. 5 1
      src/main/java/org/springblade/modules/desk/service/impl/NoticeServiceImpl.java
  16. 3 0
      src/main/java/org/springblade/modules/desk/vo/NoticeVO.java
  17. 1 1
      src/main/resources/application-dev.yml
  18. 1 1
      src/main/resources/application-prod.yml
  19. 1 1
      src/main/resources/application-test.yml
  20. 1 1
      src/main/resources/templates/code.properties
  21. 1 1
      src/test/resources/application-dev.yml
  22. 1 1
      src/test/resources/templates/code.properties

+ 78 - 0
doc/sql/bladex-datascope-update.sql

@@ -0,0 +1,78 @@
+/*
+ Navicat Premium Data Transfer
+
+ Source Server         : mysql_localhost
+ Source Server Type    : MySQL
+ Source Server Version : 50723
+ Source Host           : localhost:3306
+ Source Schema         : bladex_boot
+
+ Target Server Type    : MySQL
+ Target Server Version : 50723
+ File Encoding         : 65001
+
+ Date: 20/06/2019 00:31:21
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for blade_data_scope
+-- ----------------------------
+DROP TABLE IF EXISTS `blade_data_scope`;
+CREATE TABLE `blade_data_scope`  (
+  `id` bigint(64) NOT NULL COMMENT '主键',
+  `menu_id` bigint(64) NULL DEFAULT NULL COMMENT '菜单主键',
+  `resource_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '资源编号',
+  `scope_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '数据权限名称',
+  `scope_class` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '数据权限类名',
+  `scope_column` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '数据权限字段',
+  `scope_type` int(2) NULL DEFAULT NULL COMMENT '数据权限类型',
+  `scope_value` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '数据权限值域',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '数据权限备注',
+  `create_user` bigint(64) NULL DEFAULT NULL COMMENT '创建人',
+  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
+  `update_user` bigint(64) NULL DEFAULT NULL COMMENT '修改人',
+  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
+  `status` int(2) NULL DEFAULT NULL COMMENT '状态',
+  `is_deleted` int(2) NULL DEFAULT NULL COMMENT '是否已删除',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
+
+-- ----------------------------
+-- Table structure for blade_role_scope
+-- ----------------------------
+DROP TABLE IF EXISTS `blade_role_scope`;
+CREATE TABLE `blade_role_scope`  (
+  `id` bigint(64) NOT NULL COMMENT '主键',
+  `scope_id` bigint(64) NULL DEFAULT NULL COMMENT '数据权限id',
+  `role_id` bigint(64) NULL DEFAULT NULL COMMENT '角色id',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
+
+SET FOREIGN_KEY_CHECKS = 1;
+
+-- ----------------------------
+-- 部门表增加字段
+-- ----------------------------
+ALTER TABLE `blade_dept`
+    ADD COLUMN `ancestors` varchar(2000) NULL COMMENT '祖级列表' AFTER `parent_id`,
+    ADD COLUMN `dept_category` int(2) NULL COMMENT '部门类型' AFTER `ancestors`;
+
+UPDATE `blade_dept` SET `tenant_id` = '000000', `parent_id` = 0, `ancestors` = '0', `dept_category` = 1, `dept_name` = '刀锋科技', `full_name` = '江苏刀锋科技有限公司', `sort` = 1, `remark` = NULL, `is_deleted` = 0 WHERE `id` = 1123598813738675201;
+UPDATE `blade_dept` SET `tenant_id` = '000000', `parent_id` = 1123598813738675201, `ancestors` = '0,1123598813738675201', `dept_category` = 1, `dept_name` = '常州刀锋', `full_name` = '常州刀锋科技有限公司', `sort` = 1, `remark` = NULL, `is_deleted` = 0 WHERE `id` = 1123598813738675202;
+UPDATE `blade_dept` SET `tenant_id` = '000000', `parent_id` = 1123598813738675201, `ancestors` = '0,1123598813738675201', `dept_category` = 1, `dept_name` = '苏州刀锋', `full_name` = '苏州刀锋科技有限公司', `sort` = 1, `remark` = NULL, `is_deleted` = 0 WHERE `id` = 1123598813738675203;
+
+-- ----------------------------
+-- 增加字典项
+-- ----------------------------
+INSERT INTO `blade_dict`(`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_deleted`) VALUES (1123598814738675227, 0, 'org_category', -1, '机构类型', 7, NULL, 0);
+INSERT INTO `blade_dict`(`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_deleted`) VALUES (1123598814738675228, 1123598814738675227, 'org_category', 1, '公司', 1, NULL, 0);
+INSERT INTO `blade_dict`(`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_deleted`) VALUES (1123598814738675229, 1123598814738675227, 'org_category', 2, '部门', 2, NULL, 0);
+INSERT INTO `blade_dict`(`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_deleted`) VALUES (1123598814738675230, 0, 'data_scope', -1, '数据权限', 8, NULL, 0);
+INSERT INTO `blade_dict`(`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_deleted`) VALUES (1123598814738675231, 1123598814738675230, 'data_scope', 1, '全部可见', 1, NULL, 0);
+INSERT INTO `blade_dict`(`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_deleted`) VALUES (1123598814738675232, 1123598814738675230, 'data_scope', 2, '本人可见', 2, NULL, 0);
+INSERT INTO `blade_dict`(`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_deleted`) VALUES (1123598814738675233, 1123598814738675230, 'data_scope', 3, '所在机构可见', 3, NULL, 0);
+INSERT INTO `blade_dict`(`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_deleted`) VALUES (1123598814738675234, 1123598814738675230, 'data_scope', 4, '所在机构及子级可见', 4, NULL, 0);
+INSERT INTO `blade_dict`(`id`, `parent_id`, `code`, `dict_key`, `dict_value`, `sort`, `remark`, `is_deleted`) VALUES (1123598814738675235, 1123598814738675230, 'data_scope', 5, '自定义', 5, NULL, 0);

+ 0 - 26
doc/sql/bladex-tenantid-update.sql

@@ -1,26 +0,0 @@
-ALTER TABLE `blade_dept`
-    CHANGE COLUMN `tenant_code` `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;
-
-ALTER TABLE `blade_log_api`
-    CHANGE COLUMN `tenant_code` `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;
-
-ALTER TABLE `blade_log_error`
-    CHANGE COLUMN `tenant_code` `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;
-
-ALTER TABLE `blade_log_usual`
-    CHANGE COLUMN `tenant_code` `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;
-
-ALTER TABLE `blade_notice`
-    CHANGE COLUMN `tenant_code` `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;
-
-ALTER TABLE `blade_oss`
-    CHANGE COLUMN `tenant_code` `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;
-
-ALTER TABLE `blade_role`
-    CHANGE COLUMN `tenant_code` `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;
-
-ALTER TABLE `blade_tenant`
-    CHANGE COLUMN `tenant_code` `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;
-
-ALTER TABLE `blade_user`
-    CHANGE COLUMN `tenant_code` `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '000000' COMMENT '租户ID' AFTER `id`;

+ 3 - 3
pom.xml

@@ -7,10 +7,10 @@
     <groupId>org.springblade</groupId>
     <artifactId>BladeX-Boot</artifactId>
     <packaging>jar</packaging>
-    <version>2.0.3.RELEASE</version>
+    <version>2.0.4.RELEASE</version>
 
     <properties>
-        <bladex.tool.version>2.0.3.RELEASE</bladex.tool.version>
+        <bladex.tool.version>2.0.4.RELEASE</bladex.tool.version>
 
         <java.version>1.8</java.version>
         <maven.plugin.version>3.8.1</maven.plugin.version>
@@ -24,7 +24,7 @@
         <protostuff.version>1.6.0</protostuff.version>
         <flowable.version>6.4.1</flowable.version>
 
-        <spring.boot.version>2.1.5.RELEASE</spring.boot.version>
+        <spring.boot.version>2.1.6.RELEASE</spring.boot.version>
         <spring.platform.version>Cairo-SR8</spring.platform.version>
 
         <!-- 推荐使用Harbor -->

+ 81 - 0
src/main/java/org/springblade/modules/auth/controller/AuthController.java

@@ -0,0 +1,81 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.auth.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiSort;
+import lombok.AllArgsConstructor;
+import org.springblade.core.launch.constant.AppConstant;
+import org.springblade.core.log.annotation.ApiLog;
+import org.springblade.core.tool.support.Kv;
+import org.springblade.core.tool.utils.WebUtil;
+import org.springblade.modules.auth.granter.ITokenGranter;
+import org.springblade.modules.auth.granter.TokenGranterBuilder;
+import org.springblade.modules.auth.granter.TokenParameter;
+import org.springblade.modules.auth.utils.TokenUtil;
+import org.springblade.modules.system.entity.UserInfo;
+import org.springblade.modules.system.service.IUserService;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 认证模块
+ *
+ * @author Chill
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping(AppConstant.APPLICATION_AUTH_NAME)
+@ApiSort(1)
+@Api(value = "用户授权认证", tags = "授权接口")
+public class AuthController {
+
+	private IUserService service;
+
+	@ApiLog("登录用户验证")
+	@PostMapping("/oauth/token")
+	@ApiOperation(value = "获取认证token", notes = "传入租户ID:tenantId,账号:account,密码:password")
+	public Kv token(@ApiParam(value = "租户ID", required = true) @RequestParam(defaultValue = "000000", required = false) String tenantId,
+					@ApiParam(value = "账号", required = true) @RequestParam(required = false) String username,
+					@ApiParam(value = "密码", required = true) @RequestParam(required = false) String password) {
+
+		Kv authInfo = Kv.create();
+
+		String grantType = WebUtil.getRequest().getParameter("grant_type");
+		String refreshToken = WebUtil.getRequest().getParameter("refresh_token");
+
+		TokenParameter tokenParameter = new TokenParameter();
+		tokenParameter.getArgs().set("tenantId", tenantId).set("username", username).set("password", password).set("grantType", grantType).set("refreshToken", refreshToken);
+
+		ITokenGranter granter = TokenGranterBuilder.getGranter(grantType);
+		UserInfo userInfo = granter.grant(service, tokenParameter);
+
+		if (userInfo == null || userInfo.getUser() == null) {
+			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "用户名或密码不正确");
+		}
+
+		return TokenUtil.createAuthInfo(userInfo);
+	}
+
+
+}

+ 45 - 0
src/main/java/org/springblade/modules/auth/enums/BladeUserEnum.java

@@ -0,0 +1,45 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.auth.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 用户类型枚举
+ *
+ * @author Chill
+ */
+@Getter
+@AllArgsConstructor
+public enum BladeUserEnum {
+
+	/**
+	 * web
+	 */
+	WEB("web", 1),
+
+	/**
+	 * app
+	 */
+	APP("app", 2),
+	;
+
+	final String name;
+	final int category;
+
+}

+ 38 - 0
src/main/java/org/springblade/modules/auth/granter/ITokenGranter.java

@@ -0,0 +1,38 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.auth.granter;
+
+import org.springblade.modules.system.entity.UserInfo;
+import org.springblade.modules.system.service.IUserService;
+
+/**
+ * 授权认证统一接口.
+ *
+ * @author Chill
+ */
+public interface ITokenGranter {
+
+	/**
+	 * 获取用户信息
+	 *
+	 * @param service        用户模块业务
+	 * @param tokenParameter 授权参数
+	 * @return UserInfo
+	 */
+	UserInfo grant(IUserService service, TokenParameter tokenParameter);
+
+}

+ 59 - 0
src/main/java/org/springblade/modules/auth/granter/PasswordTokenGranter.java

@@ -0,0 +1,59 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.auth.granter;
+
+import org.springblade.core.tool.utils.DigestUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.WebUtil;
+import org.springblade.modules.auth.enums.BladeUserEnum;
+import org.springblade.modules.auth.utils.TokenUtil;
+import org.springblade.modules.system.entity.UserInfo;
+import org.springblade.modules.system.service.IUserService;
+
+/**
+ * PasswordTokenGranter
+ *
+ * @author Chill
+ */
+public class PasswordTokenGranter implements ITokenGranter {
+
+	public static final String GRANT_TYPE = "password";
+
+	@Override
+	public UserInfo grant(IUserService service, TokenParameter tokenParameter) {
+		String tenantId = tokenParameter.getArgs().getStr("tenantId");
+		String username = tokenParameter.getArgs().getStr("username");
+		String password = tokenParameter.getArgs().getStr("password");
+		if (Func.isNoneBlank(username, password)) {
+			// 获取用户类型
+			String userType = Func.toStr(WebUtil.getRequest().getHeader(TokenUtil.USER_TYPE_HEADER_KEY), TokenUtil.DEFAULT_USER_TYPE);
+			UserInfo userInfo;
+			// 根据不同用户类型调用对应的接口返回数据,用户可自行拓展
+			if (userType.equals(BladeUserEnum.WEB.getName())) {
+				userInfo = service.userInfo(tenantId, username, DigestUtil.encrypt(password));
+			} else if (userType.equals(BladeUserEnum.APP.getName())) {
+				userInfo = service.userInfo(tenantId, username, DigestUtil.encrypt(password));
+			} else {
+				userInfo = service.userInfo(tenantId, username, DigestUtil.encrypt(password));
+			}
+			return userInfo;
+		} else {
+			return null;
+		}
+	}
+
+}

+ 53 - 0
src/main/java/org/springblade/modules/auth/granter/RefreshTokenGranter.java

@@ -0,0 +1,53 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.auth.granter;
+
+import io.jsonwebtoken.Claims;
+import org.springblade.core.launch.constant.TokenConstant;
+import org.springblade.core.secure.utils.SecureUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.modules.system.entity.UserInfo;
+import org.springblade.modules.system.service.IUserService;
+
+import java.util.Objects;
+
+/**
+ * RefreshTokenGranter
+ *
+ * @author Chill
+ */
+public class RefreshTokenGranter implements ITokenGranter {
+
+	public static final String GRANT_TYPE = "refresh_token";
+
+	@Override
+	public UserInfo grant(IUserService service, TokenParameter tokenParameter) {
+		String grantType = tokenParameter.getArgs().getStr("grantType");
+		String refreshToken = tokenParameter.getArgs().getStr("refreshToken");
+		if (Func.isNoneBlank(grantType, refreshToken) && grantType.equals(TokenConstant.REFRESH_TOKEN)) {
+			Claims claims = SecureUtil.parseJWT(refreshToken);
+			String tokenType = Func.toStr(Objects.requireNonNull(claims).get(TokenConstant.TOKEN_TYPE));
+			if (tokenType.equals(TokenConstant.REFRESH_TOKEN)) {
+				return service.userInfo(Func.toLong(claims.get(TokenConstant.USER_ID)));
+			} else {
+				return null;
+			}
+		} else {
+			return null;
+		}
+	}
+}

+ 52 - 0
src/main/java/org/springblade/modules/auth/granter/TokenGranterBuilder.java

@@ -0,0 +1,52 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.auth.granter;
+
+import lombok.AllArgsConstructor;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * TokenGranterBuilder
+ *
+ * @author Chill
+ */
+@AllArgsConstructor
+public class TokenGranterBuilder {
+
+	/**
+	 * TokenGranter缓存池子
+	 */
+	private static Map<String, ITokenGranter> granterPool = new ConcurrentHashMap<>();
+
+	static {
+		granterPool.put(PasswordTokenGranter.GRANT_TYPE, new PasswordTokenGranter());
+		granterPool.put(RefreshTokenGranter.GRANT_TYPE, new RefreshTokenGranter());
+	}
+
+	/**
+	 * 获取TokenGranter
+	 *
+	 * @param grantType 授权类型
+	 * @return ITokenGranter
+	 */
+	public static ITokenGranter getGranter(String grantType) {
+		return granterPool.get(grantType);
+	}
+
+}

+ 32 - 0
src/main/java/org/springblade/modules/auth/granter/TokenParameter.java

@@ -0,0 +1,32 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.auth.granter;
+
+import lombok.Data;
+import org.springblade.core.tool.support.Kv;
+
+/**
+ * TokenParameter
+ *
+ * @author Chill
+ */
+@Data
+public class TokenParameter {
+
+	private Kv args = Kv.create();
+
+}

+ 45 - 65
src/main/java/org/springblade/modules/auth/AuthController.java → src/main/java/org/springblade/modules/auth/utils/TokenUtil.java

@@ -14,91 +14,56 @@
  *  this software without specific prior written permission.
  *  Author: Chill 庄骞 (smallchill@163.com)
  */
-package org.springblade.modules.auth;
+package org.springblade.modules.auth.utils;
 
-import io.jsonwebtoken.Claims;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiSort;
-import lombok.AllArgsConstructor;
-import org.springblade.core.launch.constant.AppConstant;
 import org.springblade.core.launch.constant.TokenConstant;
-import org.springblade.core.log.annotation.ApiLog;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.support.Kv;
-import org.springblade.core.tool.utils.DigestUtil;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.WebUtil;
 import org.springblade.modules.system.entity.User;
 import org.springblade.modules.system.entity.UserInfo;
-import org.springblade.modules.system.service.IUserService;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletResponse;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Objects;
 
 /**
- * 认证模块
+ * 认证工具类
  *
  * @author Chill
  */
-@RestController
-@AllArgsConstructor
-@RequestMapping(AppConstant.APPLICATION_AUTH_NAME)
-@ApiSort(1)
-@Api(value = "用户授权认证", tags = "授权接口")
-public class AuthController {
+public class TokenUtil {
 
-	IUserService service;
+	public final static String AVATAR = TokenConstant.AVATAR;
+	public final static String ACCOUNT = TokenConstant.ACCOUNT;
+	public final static String USER_NAME = TokenConstant.USER_NAME;
+	public final static String NICK_NAME = TokenConstant.NICK_NAME;
+	public final static String USER_ID = TokenConstant.USER_ID;
+	public final static String DEPT_ID = TokenConstant.DEPT_ID;
+	public final static String ROLE_ID = TokenConstant.ROLE_ID;
+	public final static String ROLE_NAME = TokenConstant.ROLE_NAME;
+	public final static String TENANT_ID = TokenConstant.TENANT_ID;
+	public final static String CLIENT_ID = TokenConstant.CLIENT_ID;
+	public final static String LICENSE = TokenConstant.LICENSE;
+	public final static String LICENSE_NAME = TokenConstant.LICENSE_NAME;
 
-	@ApiLog("登录用户验证")
-	@PostMapping("/oauth/token")
-	@ApiOperation(value = "获取认证token", notes = "传入租户ID:tenantId,账号:account,密码:password")
-	public Kv token(@ApiParam(value = "租户ID", required = true) @RequestParam(defaultValue = "000000", required = false) String tenantId,
-					@ApiParam(value = "账号", required = true) @RequestParam(required = false) String username,
-					@ApiParam(value = "密码", required = true) @RequestParam(required = false)  String password) {
 
-		Kv authInfo = Kv.create();
-
-		String grantType = WebUtil.getRequest().getParameter("grant_type");
-		String refreshToken = WebUtil.getRequest().getParameter("refresh_token");
-
-		UserInfo userInfo = null;
-
-		if (Func.isNoneBlank(username, password)) {
-			userInfo = service.userInfo(tenantId, username, DigestUtil.encrypt(password));
-		} else if (Func.isNoneBlank(grantType, refreshToken) && grantType.equals(TokenConstant.REFRESH_TOKEN)) {
-			Claims claims = SecureUtil.parseJWT(refreshToken);
-			String tokenType = Func.toStr(Objects.requireNonNull(claims).get(TokenConstant.TOKEN_TYPE));
-			if (tokenType.equals(TokenConstant.REFRESH_TOKEN)) {
-				userInfo = service.userInfo(Func.toLong(claims.get(TokenConstant.USER_ID)));
-			}
-		} else {
-			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "接口调用不合法");
-		}
-
-		if (userInfo == null || userInfo.getUser() == null) {
-			return authInfo.set("error_code", HttpServletResponse.SC_BAD_REQUEST).set("error_description", "用户名或密码不正确");
-		}
-
-		return createAuthInfo(userInfo);
-	}
+	public final static String TENANT_HEADER_KEY = "Tenant-Id";
+	public final static String DEFAULT_TENANT_ID = "000000";
+	public final static String USER_TYPE_HEADER_KEY = "User-Type";
+	public final static String DEFAULT_USER_TYPE = "web";
+	public final static String USER_NOT_FOUND = "用户名或密码错误";
+	public final static String HEADER_KEY = "Authorization";
+	public final static String HEADER_PREFIX = "Basic ";
+	public final static String DEFAULT_AVATAR = "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png";
 
-	private String createRefreshToken(UserInfo userInfo) {
-		User user = userInfo.getUser();
-		Map<String, String> param = new HashMap<>(16);
-		param.put(TokenConstant.TOKEN_TYPE, TokenConstant.REFRESH_TOKEN);
-		param.put(TokenConstant.USER_ID, Func.toStr(user.getId()));
-		return SecureUtil.createJWT(param, "audience", "issuser", TokenConstant.REFRESH_TOKEN);
-	}
-
-	private Kv createAuthInfo(UserInfo userInfo) {
+	/**
+	 * 创建认证token
+	 *
+	 * @param userInfo 用户信息
+	 * @return token
+	 */
+	public static Kv createAuthInfo(UserInfo userInfo) {
 		Kv authInfo = Kv.create();
 		User user = userInfo.getUser();
 		//设置jwt参数
@@ -106,6 +71,7 @@ public class AuthController {
 		param.put(TokenConstant.TOKEN_TYPE, TokenConstant.ACCESS_TOKEN);
 		param.put(TokenConstant.TENANT_ID, user.getTenantId());
 		param.put(TokenConstant.USER_ID, Func.toStr(user.getId()));
+		param.put(TokenConstant.DEPT_ID, user.getDeptId());
 		param.put(TokenConstant.ROLE_ID, user.getRoleId());
 		param.put(TokenConstant.ACCOUNT, user.getAccount());
 		param.put(TokenConstant.USER_NAME, user.getAccount());
@@ -131,4 +97,18 @@ public class AuthController {
 		}
 	}
 
+	/**
+	 * 创建refreshToken
+	 *
+	 * @param userInfo 用户信息
+	 * @return refreshToken
+	 */
+	private static String createRefreshToken(UserInfo userInfo) {
+		User user = userInfo.getUser();
+		Map<String, String> param = new HashMap<>(16);
+		param.put(TokenConstant.TOKEN_TYPE, TokenConstant.REFRESH_TOKEN);
+		param.put(TokenConstant.USER_ID, Func.toStr(user.getId()));
+		return SecureUtil.createJWT(param, "audience", "issuser", TokenConstant.REFRESH_TOKEN);
+	}
+
 }

+ 2 - 1
src/main/java/org/springblade/modules/desk/mapper/NoticeMapper.java

@@ -19,6 +19,7 @@ package org.springblade.modules.desk.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.modules.desk.entity.Notice;
+import org.springblade.modules.desk.vo.NoticeVO;
 
 import java.util.List;
 
@@ -42,6 +43,6 @@ public interface NoticeMapper extends BaseMapper<Notice> {
 	 * @param notice
 	 * @return
 	 */
-	List<Notice> selectNoticePage(IPage page, Notice notice);
+	List<NoticeVO> selectNoticePage(IPage page, NoticeVO notice);
 
 }

+ 28 - 14
src/main/java/org/springblade/modules/desk/mapper/NoticeMapper.xml

@@ -16,24 +16,38 @@
         <result column="content" property="content"/>
     </resultMap>
 
-    <!-- 通用查询结果列 -->
-    <sql id="baseColumnList">
-        select id,
-        create_user AS createUser,
-        create_time AS createTime,
-        update_user AS updateUser,
-        update_time AS updateTime,
-        status,
-        is_deleted AS isDeleted,
-        title, content
-    </sql>
+    <!-- 通用查询映射结果 -->
+    <resultMap id="noticeVOResultMap" type="org.springblade.modules.desk.vo.NoticeVO">
+        <result column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="release_time" property="releaseTime"/>
+        <result column="title" property="title"/>
+        <result column="content" property="content"/>
+    </resultMap>
 
     <select id="topList" resultMap="noticeResultMap">
         select * from blade_notice limit #{number}
     </select>
 
-    <select id="selectNoticePage" resultMap="noticeResultMap">
-        select * from blade_notice where title like concat('%', #{notice.title}, '%') and is_deleted = 0
+    <select id="selectNoticePage" resultMap="noticeVOResultMap">
+        SELECT
+        n.*,
+        d.dict_value AS categoryName
+        FROM
+        blade_notice n
+        LEFT JOIN ( SELECT * FROM blade_dict WHERE CODE = 'notice' ) d ON n.category = d.dict_key
+        WHERE
+        n.is_deleted = 0 and n.tenant_id = #{notice.tenantId}
+        <if test="notice.title!=null">
+            and n.title like concat('%', #{notice.title}, '%')
+        </if>
+        <if test="notice.category!=null">
+            and n.category = #{notice.category}
+        </if>
     </select>
-
 </mapper>

+ 2 - 1
src/main/java/org/springblade/modules/desk/service/INoticeService.java

@@ -19,6 +19,7 @@ package org.springblade.modules.desk.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.core.mp.base.BaseService;
 import org.springblade.modules.desk.entity.Notice;
+import org.springblade.modules.desk.vo.NoticeVO;
 
 /**
  * 服务类
@@ -33,6 +34,6 @@ public interface INoticeService extends BaseService<Notice> {
 	 * @param notice
 	 * @return
 	 */
-	IPage<Notice> selectNoticePage(IPage<Notice> page, Notice notice);
+	IPage<NoticeVO> selectNoticePage(IPage<NoticeVO> page, NoticeVO notice);
 
 }

+ 5 - 1
src/main/java/org/springblade/modules/desk/service/impl/NoticeServiceImpl.java

@@ -18,9 +18,11 @@ package org.springblade.modules.desk.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.modules.desk.entity.Notice;
 import org.springblade.modules.desk.mapper.NoticeMapper;
 import org.springblade.modules.desk.service.INoticeService;
+import org.springblade.modules.desk.vo.NoticeVO;
 import org.springframework.stereotype.Service;
 
 /**
@@ -32,7 +34,9 @@ import org.springframework.stereotype.Service;
 public class NoticeServiceImpl extends BaseServiceImpl<NoticeMapper, Notice> implements INoticeService {
 
 	@Override
-	public IPage<Notice> selectNoticePage(IPage<Notice> page, Notice notice) {
+	public IPage<NoticeVO> selectNoticePage(IPage<NoticeVO> page, NoticeVO notice) {
+		// 若不使用mybatis-plus自带的分页方法,则不会自动带入tenantId,所以我们需要自行注入
+		notice.setTenantId(SecureUtil.getTenantId());
 		return page.setRecords(baseMapper.selectNoticePage(page, notice));
 	}
 

+ 3 - 0
src/main/java/org/springblade/modules/desk/vo/NoticeVO.java

@@ -17,4 +17,7 @@ public class NoticeVO extends Notice {
 	@ApiModelProperty(value = "通知类型名")
 	private String categoryName;
 
+	@ApiModelProperty(value = "租户编号")
+	private String tenantId;
+
 }

+ 1 - 1
src/main/resources/application-dev.yml

@@ -12,7 +12,7 @@ spring:
     #  nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
     #  commandTimeout: 5000
   datasource:
-    url: jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
+    url: jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
     username: root
     password: root
     driver-class-name: com.mysql.cj.jdbc.Driver

+ 1 - 1
src/main/resources/application-prod.yml

@@ -12,7 +12,7 @@ spring:
     #  nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
     #  commandTimeout: 5000
   datasource:
-    url: jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
+    url: jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
     username: root
     password: root
     driver-class-name: com.mysql.cj.jdbc.Driver

+ 1 - 1
src/main/resources/application-test.yml

@@ -12,7 +12,7 @@ spring:
     #  nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
     #  commandTimeout: 5000
   datasource:
-    url: jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
+    url: jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
     username: root
     password: root
     driver-class-name: com.mysql.cj.jdbc.Driver

+ 1 - 1
src/main/resources/templates/code.properties

@@ -1,5 +1,5 @@
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
-spring.datasource.url=jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&serverTimezone=GMT%2B8
+spring.datasource.url=jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
 spring.datasource.username=root
 spring.datasource.password=root
 author=BladeX

+ 1 - 1
src/test/resources/application-dev.yml

@@ -12,7 +12,7 @@ spring:
     #  nodes: 127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
     #  commandTimeout: 5000
   datasource:
-    url: jdbc:mysql://localhost:3306/bladex?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8
+    url: jdbc:mysql://localhost:3306/bladex?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
     username: root
     password: root
     driver-class-name: com.mysql.cj.jdbc.Driver

+ 1 - 1
src/test/resources/templates/code.properties

@@ -1,5 +1,5 @@
 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
-spring.datasource.url=jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&serverTimezone=GMT%2B8
+spring.datasource.url=jdbc:mysql://localhost:3306/bladex_boot?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
 spring.datasource.username=root
 spring.datasource.password=root
 author=BladeX