🎉 2.7.2.RELEASE 集成JustAuth支持第三方登录

This commit is contained in:
smallchill 2020-08-20 00:22:10 +08:00
parent 7c58bc9207
commit e74f649658
59 changed files with 788 additions and 3368 deletions

View File

@ -1,9 +1,9 @@
<p align="center">
<img src="https://img.shields.io/badge/Release-V2.7.1-green.svg" alt="Downloads">
<img src="https://img.shields.io/badge/Release-V2.7.2-green.svg" alt="Downloads">
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" alt="Build Status">
<img src="https://img.shields.io/badge/license-Apache%202-blue.svg" alt="Build Status">
<img src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR5-blue.svg" alt="Coverage Status">
<img src="https://img.shields.io/badge/Spring%20Boot-2.2.7.RELEASE-blue.svg" alt="Downloads">
<img src="https://img.shields.io/badge/Spring%20Cloud-Hoxton.SR7-blue.svg" alt="Coverage Status">
<img src="https://img.shields.io/badge/Spring%20Boot-2.2.9.RELEASE-blue.svg" alt="Downloads">
<a target="_blank" href="https://bladex.vip">
<img src="https://img.shields.io/badge/Author-Small%20Chill-ff69b4.svg" alt="Downloads">
</a>
@ -59,7 +59,8 @@ SpringBlade
* 交流一群:`477853168`(满)
* 交流二群:`751253339`(满)
* 交流三群:`784729540`(满)
* 交流四群:`1034621754`
* 交流四群:`1034621754`(满)
* 交流五群:`946350912`
## 在线演示
* Saber-基于Vue[https://saber.bladex.vip](https://saber.bladex.vip)

View File

@ -8,7 +8,7 @@
<parent>
<artifactId>SpringBlade</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<artifactId>blade-auth</artifactId>
@ -38,6 +38,11 @@
<artifactId>blade-core-log</artifactId>
<version>${blade.tool.version}</version>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-social</artifactId>
<version>${blade.tool.version}</version>
</dependency>
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-user-api</artifactId>

View File

@ -0,0 +1,92 @@
/**
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springblade.auth.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springblade.core.social.props.SocialProperties;
import org.springblade.core.social.utils.SocialUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 第三方登陆端点
*
* @author Chill
*/
@Slf4j
@RestController
@AllArgsConstructor
@ConditionalOnProperty(value = "social.enabled", havingValue = "true")
@Api(value = "第三方登陆", tags = "第三方登陆端点")
public class SocialController {
private final SocialProperties socialProperties;
/**
* 授权完毕跳转
*/
@ApiOperation(value = "授权完毕跳转")
@RequestMapping("/oauth/render/{source}")
public void renderAuth(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
response.sendRedirect(authorizeUrl);
}
/**
* 获取认证信息
*/
@ApiOperation(value = "获取认证信息")
@RequestMapping("/oauth/callback/{source}")
public Object login(@PathVariable("source") String source, AuthCallback callback) {
AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
return authRequest.login(callback);
}
/**
* 撤销授权
*/
@ApiOperation(value = "撤销授权")
@RequestMapping("/oauth/revoke/{source}/{token}")
public Object revokeAuth(@PathVariable("source") String source, @PathVariable("token") String token) {
AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
return authRequest.revoke(AuthToken.builder().accessToken(token).build());
}
/**
* 续期accessToken
*/
@ApiOperation(value = "续期令牌")
@RequestMapping("/oauth/refresh/{source}")
public Object refreshAuth(@PathVariable("source") String source, String token) {
AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
return authRequest.refresh(AuthToken.builder().refreshToken(token).build());
}
}

View File

@ -0,0 +1,91 @@
/**
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springblade.auth.granter;
import lombok.AllArgsConstructor;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import org.springblade.auth.utils.TokenUtil;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.social.props.SocialProperties;
import org.springblade.core.social.utils.SocialUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.WebUtil;
import org.springblade.system.user.entity.UserInfo;
import org.springblade.system.user.entity.UserOauth;
import org.springblade.system.user.feign.IUserClient;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
/**
* SocialTokenGranter
*
* @author Chill
*/
@Component
@AllArgsConstructor
public class SocialTokenGranter implements ITokenGranter {
public static final String GRANT_TYPE = "social";
private static final Integer AUTH_SUCCESS_CODE = 2000;
private final IUserClient userClient;
private final SocialProperties socialProperties;
@Override
public UserInfo grant(TokenParameter tokenParameter) {
HttpServletRequest request = WebUtil.getRequest();
String tenantId = Func.toStr(request.getHeader(TokenUtil.TENANT_HEADER_KEY), TokenUtil.DEFAULT_TENANT_ID);
// 开放平台来源
String sourceParameter = request.getParameter("source");
// 匹配是否有别名定义
String source = socialProperties.getAlias().getOrDefault(sourceParameter, sourceParameter);
// 开放平台授权码
String code = request.getParameter("code");
// 开放平台状态吗
String state = request.getParameter("state");
// 获取开放平台授权数据
AuthRequest authRequest = SocialUtil.getAuthRequest(source, socialProperties);
AuthCallback authCallback = new AuthCallback();
authCallback.setCode(code);
authCallback.setState(state);
AuthResponse authResponse = authRequest.login(authCallback);
AuthUser authUser;
if (authResponse.getCode() == AUTH_SUCCESS_CODE) {
authUser = (AuthUser) authResponse.getData();
} else {
throw new ServiceException("social grant failure, auth response is not success");
}
// 组装数据
UserOauth userOauth = Objects.requireNonNull(BeanUtil.copy(authUser, UserOauth.class));
userOauth.setSource(authUser.getSource());
userOauth.setTenantId(tenantId);
userOauth.setUuid(authUser.getUuid());
// 远程调用获取认证信息
R<UserInfo> result = userClient.userAuthInfo(userOauth);
return result.getData();
}
}

View File

@ -34,12 +34,13 @@ public class TokenGranterBuilder {
/**
* TokenGranter缓存池
*/
private static Map<String, ITokenGranter> granterPool = new ConcurrentHashMap<>();
private static final Map<String, ITokenGranter> GRANTER_POOL = new ConcurrentHashMap<>();
static {
granterPool.put(PasswordTokenGranter.GRANT_TYPE, SpringUtil.getBean(PasswordTokenGranter.class));
granterPool.put(CaptchaTokenGranter.GRANT_TYPE, SpringUtil.getBean(CaptchaTokenGranter.class));
granterPool.put(RefreshTokenGranter.GRANT_TYPE, SpringUtil.getBean(RefreshTokenGranter.class));
GRANTER_POOL.put(PasswordTokenGranter.GRANT_TYPE, SpringUtil.getBean(PasswordTokenGranter.class));
GRANTER_POOL.put(CaptchaTokenGranter.GRANT_TYPE, SpringUtil.getBean(CaptchaTokenGranter.class));
GRANTER_POOL.put(RefreshTokenGranter.GRANT_TYPE, SpringUtil.getBean(RefreshTokenGranter.class));
GRANTER_POOL.put(SocialTokenGranter.GRANT_TYPE, SpringUtil.getBean(SocialTokenGranter.class));
}
/**
@ -49,7 +50,7 @@ public class TokenGranterBuilder {
* @return ITokenGranter
*/
public static ITokenGranter getGranter(String grantType) {
ITokenGranter tokenGranter = granterPool.get(Func.toStr(grantType, PasswordTokenGranter.GRANT_TYPE));
ITokenGranter tokenGranter = GRANTER_POOL.get(Func.toStr(grantType, PasswordTokenGranter.GRANT_TYPE));
if (tokenGranter == null) {
throw new SecureException("no grantType was found");
} else {

View File

@ -58,6 +58,7 @@ public class TokenUtil {
Map<String, String> param = new HashMap<>(16);
param.put(TokenConstant.TOKEN_TYPE, TokenConstant.ACCESS_TOKEN);
param.put(TokenConstant.TENANT_ID, user.getTenantId());
param.put(TokenConstant.OAUTH_ID, userInfo.getOauthId());
param.put(TokenConstant.USER_ID, Func.toStr(user.getId()));
param.put(TokenConstant.ROLE_ID, user.getRoleId());
param.put(TokenConstant.ACCOUNT, user.getAccount());
@ -66,6 +67,9 @@ public class TokenUtil {
TokenInfo accessToken = SecureUtil.createJWT(param, "audience", "issuser", TokenConstant.ACCESS_TOKEN);
AuthInfo authInfo = new AuthInfo();
authInfo.setUserId(user.getId());
authInfo.setTenantId(user.getTenantId());
authInfo.setOauthId(userInfo.getOauthId());
authInfo.setAccount(user.getAccount());
authInfo.setUserName(user.getRealName());
authInfo.setAuthority(Func.join(userInfo.getRoles()));

View File

@ -9,3 +9,8 @@ spring:
url: ${blade.datasource.dev.url}
username: ${blade.datasource.dev.username}
password: ${blade.datasource.dev.password}
#第三方登陆
social:
enabled: true
domain: http://127.0.0.1:1888

View File

@ -9,3 +9,8 @@ spring:
url: ${blade.datasource.prod.url}
username: ${blade.datasource.prod.username}
password: ${blade.datasource.prod.password}
#第三方登陆
social:
enabled: true
domain: http://127.0.0.1:1888

View File

@ -9,3 +9,8 @@ spring:
url: ${blade.datasource.test.url}
username: ${blade.datasource.test.username}
password: ${blade.datasource.test.password}
#第三方登陆
social:
enabled: true
domain: http://127.0.0.1:1888

View File

@ -0,0 +1,23 @@
#第三方登陆配置
social:
oauth:
GITHUB:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/github
GITEE:
client-id: 1318429408fc3b25d1b740f909586bc3550abc803ece42b309047ef82a1ba023
client-secret: 253a1964b2ac092d0c2d8682530b2564f37b210f750ab51b9129aa0f7fd015b5
redirect-uri: ${social.domain}/oauth/redirect/gitee
WECHAT_OPEN:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/wechat
QQ:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/qq
DINGTALK:
client-id: 233************
client-secret: 233************************************
redirect-uri: ${social.domain}/oauth/redirect/dingtalk

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>SpringBlade</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>SpringBlade</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -40,6 +40,7 @@ public class AuthProvider {
defaultSkipUrl.add("/v2/api-docs/**");
defaultSkipUrl.add("/v2/api-docs-ext/**");
defaultSkipUrl.add("/auth/**");
defaultSkipUrl.add("/oauth/**");
defaultSkipUrl.add("/log/**");
defaultSkipUrl.add("/menu/routes");
defaultSkipUrl.add("/menu/auth-routes");

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-ops</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.springblade</groupId>
<artifactId>blade-ops</artifactId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-ops</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-ops</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-ops</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>SpringBlade</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-service-api</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-service-api</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-service-api</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-service-api</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -16,8 +16,10 @@
package org.springblade.system.feign;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.tool.api.R;
import org.springblade.system.entity.Dept;
import org.springblade.system.entity.Role;
import org.springblade.system.entity.Tenant;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@ -141,4 +143,22 @@ public interface ISysClient {
@GetMapping(API_PREFIX + "/getRoleAlias")
String getRoleAlias(@RequestParam("id") Long id);
/**
* 获取租户
*
* @param id 主键
* @return Tenant
*/
@GetMapping(API_PREFIX + "/tenant")
R<Tenant> getTenant(@RequestParam("id") Long id);
/**
* 获取租户
*
* @param tenantId 租户id
* @return Tenant
*/
@GetMapping(API_PREFIX + "/tenant-id")
R<Tenant> getTenant(@RequestParam("tenantId") String tenantId);
}

View File

@ -15,8 +15,10 @@
*/
package org.springblade.system.feign;
import org.springblade.core.tool.api.R;
import org.springblade.system.entity.Dept;
import org.springblade.system.entity.Role;
import org.springblade.system.entity.Tenant;
import org.springframework.stereotype.Component;
import java.util.List;
@ -83,4 +85,14 @@ public class ISysClientFallback implements ISysClient {
public String getRoleAlias(Long id) {
return null;
}
@Override
public R<Tenant> getTenant(Long id) {
return null;
}
@Override
public R<Tenant> getTenant(String tenantId) {
return null;
}
}

View File

@ -0,0 +1,39 @@
/**
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springblade.system.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* GrantVO
*
* @author Chill
*/
@Data
public class GrantVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "roleIds集合")
private List<Long> roleIds;
@ApiModelProperty(value = "menuIds集合")
private List<Long> menuIds;
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-service-api</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -51,4 +51,10 @@ public class UserInfo implements Serializable {
@ApiModelProperty(value = "角色集合")
private List<String> roles;
/**
* 第三方授权id
*/
@ApiModelProperty(value = "第三方授权id")
private String oauthId;
}

View File

@ -0,0 +1,107 @@
/**
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springblade.system.user.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 实体类
*
* @author Chill
*/
@Data
@TableName("blade_user_oauth")
public class UserOauth implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@JsonSerialize(using = ToStringSerializer.class)
@ApiModelProperty(value = "主键")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 租户ID
*/
private String tenantId;
/**
* 第三方系统用户ID
*/
private String uuid;
/**
* 用户ID
*/
@JsonSerialize(using = ToStringSerializer.class)
@ApiModelProperty(value = "用户主键")
private Long userId;
/**
* 用户名
*/
private String username;
/**
* 用户昵称
*/
private String nickname;
/**
* 用户头像
*/
private String avatar;
/**
* 用户网址
*/
private String blog;
/**
* 所在公司
*/
private String company;
/**
* 位置
*/
private String location;
/**
* 用户邮箱
*/
private String email;
/**
* 用户备注各平台中的用户个人介绍
*/
private String remark;
/**
* 性别
*/
private String gender;
/**
* 用户来源
*/
private String source;
}

View File

@ -19,8 +19,11 @@ package org.springblade.system.user.feign;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.tool.api.R;
import org.springblade.system.user.entity.UserInfo;
import org.springblade.system.user.entity.UserOauth;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
/**
@ -56,4 +59,13 @@ public interface IUserClient {
@GetMapping(API_PREFIX + "/user-info")
R<UserInfo> userInfo(@RequestParam("tenantId") String tenantId, @RequestParam("account") String account, @RequestParam("password") String password);
/**
* 获取第三方平台信息
*
* @param userOauth 第三方授权用户信息
* @return UserInfo
*/
@PostMapping(API_PREFIX + "/user-auth-info")
R<UserInfo> userAuthInfo(@RequestBody UserOauth userOauth);
}

View File

@ -17,6 +17,7 @@ package org.springblade.system.user.feign;
import org.springblade.core.tool.api.R;
import org.springblade.system.user.entity.UserInfo;
import org.springblade.system.user.entity.UserOauth;
import org.springframework.stereotype.Component;
/**
@ -36,4 +37,9 @@ public class IUserClientFallback implements IUserClient {
public R<UserInfo> userInfo(String tenantId, String account, String password) {
return R.fail("未获取到账号信息");
}
@Override
public R<UserInfo> userAuthInfo(UserOauth userOauth) {
return R.fail("未获取到账号信息");
}
}

View File

@ -5,13 +5,13 @@
<parent>
<artifactId>SpringBlade</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>blade-service-api</artifactId>
<name>${project.artifactId}</name>
<version>2.7.1</version>
<version>2.7.2</version>
<packaging>pom</packaging>
<description>SpringBlade 微服务API集合</description>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-service</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>org.springblade</groupId>
<artifactId>blade-service</artifactId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-service</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-service</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -109,7 +109,7 @@ public class MenuController extends BladeController {
@ApiOperationSupport(order = 5)
@ApiOperation(value = "前端菜单数据", notes = "前端菜单数据")
public R<List<MenuVO>> routes(BladeUser user) {
List<MenuVO> list = menuService.routes(user.getRoleId());
List<MenuVO> list = menuService.routes((user == null || user.getUserId() == 0L) ? null : user.getRoleId());
return R.data(list);
}

View File

@ -28,6 +28,7 @@ import org.springblade.core.tool.node.INode;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.entity.Role;
import org.springblade.system.service.IRoleService;
import org.springblade.system.vo.GrantVO;
import org.springblade.system.vo.RoleVO;
import org.springblade.system.wrapper.RoleWrapper;
import org.springframework.web.bind.annotation.*;
@ -114,17 +115,12 @@ public class RoleController extends BladeController {
/**
* 设置菜单权限
*
* @param roleIds
* @param menuIds
* @return
*/
@PostMapping("/grant")
@ApiOperationSupport(order = 6)
@ApiOperation(value = "权限设置", notes = "传入roleId集合以及menuId集合")
public R grant(@ApiParam(value = "roleId集合", required = true) @RequestParam String roleIds,
@ApiParam(value = "menuId集合", required = true) @RequestParam String menuIds) {
boolean temp = roleService.grant(Func.toLongList(roleIds), Func.toLongList(menuIds));
public R grant(@RequestBody GrantVO grantVO) {
boolean temp = roleService.grant(grantVO.getRoleIds(), grantVO.getMenuIds());
return R.status(temp);
}

View File

@ -16,11 +16,14 @@
package org.springblade.system.feign;
import lombok.AllArgsConstructor;
import org.springblade.core.tool.api.R;
import org.springblade.system.entity.Dept;
import org.springblade.system.entity.Role;
import org.springblade.system.entity.Tenant;
import org.springblade.system.service.IDeptService;
import org.springblade.system.service.IPostService;
import org.springblade.system.service.IRoleService;
import org.springblade.system.service.ITenantService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
@ -43,6 +46,8 @@ public class SysClient implements ISysClient {
private IRoleService roleService;
private ITenantService tenantService;
@Override
@GetMapping(API_PREFIX + "/getDept")
public Dept getDept(Long id) {
@ -102,4 +107,16 @@ public class SysClient implements ISysClient {
public String getRoleAlias(Long id) {
return roleService.getById(id).getRoleAlias();
}
@Override
@GetMapping(API_PREFIX + "/tenant")
public R<Tenant> getTenant(Long id) {
return R.data(tenantService.getById(id));
}
@Override
@GetMapping(API_PREFIX + "/tenant-id")
public R<Tenant> getTenant(String tenantId) {
return R.data(tenantService.getByTenantId(tenantId));
}
}

View File

@ -35,6 +35,14 @@ public interface ITenantService extends BaseService<Tenant> {
*/
IPage<Tenant> selectTenantPage(IPage<Tenant> page, Tenant tenant);
/**
* 根据租户编号获取实体
*
* @param tenantId
* @return
*/
Tenant getByTenantId(String tenantId);
/**
* 新增
*

View File

@ -24,6 +24,7 @@ import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.node.ForestNodeMerger;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.system.dto.MenuDTO;
import org.springblade.system.entity.Menu;
import org.springblade.system.entity.RoleMenu;
@ -55,6 +56,9 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IM
@Override
public List<MenuVO> routes(String roleId) {
if (StringUtil.isBlank(roleId)) {
return null;
}
List<Menu> allMenus = baseMapper.allMenu();
List<Menu> roleMenus = baseMapper.roleMenu(Func.toLongList(roleId));
List<Menu> routes = new LinkedList<>(roleMenus);

View File

@ -53,6 +53,11 @@ public class TenantServiceImpl extends BaseServiceImpl<TenantMapper, Tenant> imp
return page.setRecords(baseMapper.selectTenantPage(page, tenant));
}
@Override
public Tenant getByTenantId(String tenantId) {
return getOne(Wrappers.<Tenant>query().lambda().eq(Tenant::getTenantId, tenantId));
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveTenant(Tenant tenant) {

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>blade-service</artifactId>
<groupId>org.springblade</groupId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -257,5 +257,15 @@ public class UserController {
EasyExcel.write(response.getOutputStream(), UserExcel.class).sheet("用户数据表").doWrite(list);
}
/**
* 第三方注册用户
*/
@PostMapping("/register-guest")
@ApiOperationSupport(order = 15)
@ApiOperation(value = "第三方注册用户", notes = "传入user")
public R registerGuest(User user, Long oauthId) {
return R.status(userService.registerGuest(user, oauthId));
}
}

View File

@ -17,10 +17,11 @@ package org.springblade.system.user.feign;
import lombok.AllArgsConstructor;
import org.springblade.core.tool.api.R;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.entity.UserInfo;
import org.springblade.system.user.entity.UserOauth;
import org.springblade.system.user.service.IUserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
@ -45,4 +46,10 @@ public class UserClient implements IUserClient {
return R.data(service.userInfo(tenantId, account, password));
}
@Override
@PostMapping(API_PREFIX + "/user-auth-info")
public R<UserInfo> userAuthInfo(UserOauth userOauth) {
return R.data(service.userInfo(userOauth));
}
}

View File

@ -0,0 +1,28 @@
/**
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springblade.system.user.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springblade.system.user.entity.UserOauth;
/**
* Mapper 接口
*
* @author Chill
*/
public interface UserOauthMapper extends BaseMapper<UserOauth> {
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.springblade.system.user.mapper.UserOauthMapper">
<!-- 通用查询映射结果 -->
<resultMap id="userResultMap" type="org.springblade.system.user.entity.UserOauth">
<result column="id" property="id"/>
<result column="tenant_id" property="tenantId"/>
<result column="user_id" property="userId"/>
<result column="username" property="username"/>
<result column="nickname" property="nickname"/>
<result column="avatar" property="avatar"/>
<result column="blog" property="blog"/>
<result column="company" property="company"/>
<result column="location" property="location"/>
<result column="email" property="email"/>
<result column="remark" property="remark"/>
<result column="gender" property="gender"/>
<result column="source" property="source"/>
</resultMap>
</mapper>

View File

@ -0,0 +1,29 @@
/**
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springblade.system.user.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springblade.system.user.entity.UserOauth;
/**
* 服务类
*
* @author Chill
*/
public interface IUserOauthService extends IService<UserOauth> {
}

View File

@ -21,6 +21,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseService;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.entity.UserInfo;
import org.springblade.system.user.entity.UserOauth;
import org.springblade.system.user.excel.UserExcel;
import java.util.List;
@ -34,7 +35,6 @@ public interface IUserService extends BaseService<User> {
/**
* 新增或修改用户
*
* @param user
* @return
*/
@ -67,6 +67,14 @@ public interface IUserService extends BaseService<User> {
*/
UserInfo userInfo(String tenantId, String account, String password);
/**
* 用户信息
*
* @param userOauth
* @return
*/
UserInfo userInfo(UserOauth userOauth);
/**
* 给用户设置角色
*
@ -126,4 +134,13 @@ public interface IUserService extends BaseService<User> {
* @return
*/
List<UserExcel> exportUser(Wrapper<User> queryWrapper);
/**
* 注册用户
*
* @param user
* @param oauthId
* @return
*/
boolean registerGuest(User user, Long oauthId);
}

View File

@ -0,0 +1,35 @@
/**
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springblade.system.user.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springblade.system.user.entity.UserOauth;
import org.springblade.system.user.mapper.UserOauthMapper;
import org.springblade.system.user.service.IUserOauthService;
import org.springframework.stereotype.Service;
/**
* 服务实现类
*
* @author Chill
*/
@Service
@AllArgsConstructor
public class UserOauthServiceImpl extends ServiceImpl<UserOauthMapper, UserOauth> implements IUserOauthService {
}

View File

@ -24,15 +24,21 @@ import lombok.AllArgsConstructor;
import org.springblade.common.constant.CommonConstant;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.*;
import org.springblade.system.entity.Tenant;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.entity.UserInfo;
import org.springblade.system.user.entity.UserOauth;
import org.springblade.system.user.excel.UserExcel;
import org.springblade.system.user.mapper.UserMapper;
import org.springblade.system.user.service.IUserOauthService;
import org.springblade.system.user.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@ -44,8 +50,11 @@ import java.util.Objects;
@Service
@AllArgsConstructor
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implements IUserService {
private static final String GUEST_NAME = "guest";
private static final String MINUS_ONE = "-1";
private ISysClient sysClient;
private IUserOauthService userOauthService;
@Override
public boolean submit(User user) {
@ -88,6 +97,30 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
return userInfo;
}
@Override
@Transactional(rollbackFor = Exception.class)
public UserInfo userInfo(UserOauth userOauth) {
UserOauth uo = userOauthService.getOne(Wrappers.<UserOauth>query().lambda().eq(UserOauth::getUuid, userOauth.getUuid()).eq(UserOauth::getSource, userOauth.getSource()));
UserInfo userInfo;
if (Func.isNotEmpty(uo) && Func.isNotEmpty(uo.getUserId())) {
userInfo = this.userInfo(uo.getUserId());
userInfo.setOauthId(Func.toStr(uo.getId()));
} else {
userInfo = new UserInfo();
if (Func.isEmpty(uo)) {
userOauthService.save(userOauth);
userInfo.setOauthId(Func.toStr(userOauth.getId()));
} else {
userInfo.setOauthId(Func.toStr(uo.getId()));
}
User user = new User();
user.setAccount(userOauth.getUsername());
userInfo.setUser(user);
userInfo.setRoles(Collections.singletonList(GUEST_NAME));
}
return userInfo;
}
@Override
public boolean grant(String userIds, String roleIds) {
User user = new User();
@ -152,4 +185,28 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
return userList;
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean registerGuest(User user, Long oauthId) {
R<Tenant> result = sysClient.getTenant(user.getTenantId());
Tenant tenant = result.getData();
if (!result.isSuccess() || tenant == null || tenant.getId() == null) {
throw new ApiException("租户信息错误!");
}
UserOauth userOauth = userOauthService.getById(oauthId);
if (userOauth == null || userOauth.getId() == null) {
throw new ApiException("第三方登陆信息错误!");
}
user.setRealName(user.getName());
user.setAvatar(userOauth.getAvatar());
user.setRoleId(MINUS_ONE);
user.setDeptId(MINUS_ONE);
user.setPostId(MINUS_ONE);
boolean userTemp = this.submit(user);
userOauth.setUserId(user.getId());
userOauth.setTenantId(user.getTenantId());
boolean oauthTemp = userOauthService.updateById(userOauth);
return (userTemp && oauthTemp);
}
}

View File

@ -7,12 +7,12 @@
<parent>
<groupId>org.springblade</groupId>
<artifactId>SpringBlade</artifactId>
<version>2.7.1</version>
<version>2.7.2</version>
</parent>
<artifactId>blade-service</artifactId>
<name>${project.artifactId}</name>
<version>2.7.1</version>
<version>2.7.2</version>
<packaging>pom</packaging>
<description>SpringBlade 微服务集合</description>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
CREATE TABLE `blade_user_oauth` (
`id` bigint(64) NOT NULL COMMENT '主键',
`tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '租户ID',
`uuid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '第三方系统用户ID',
`user_id` bigint(64) NULL DEFAULT NULL COMMENT '用户ID',
`username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '账号',
`nickname` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名',
`avatar` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '头像',
`blog` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用主页',
`company` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '公司名',
`location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '地址',
`email` varchar(255) 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 '备注',
`gender` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '性别',
`source` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '来源',
PRIMARY KEY (`id`)
) COMMENT = '用户第三方认证表';

16
pom.xml
View File

@ -5,28 +5,28 @@
<groupId>org.springblade</groupId>
<artifactId>SpringBlade</artifactId>
<version>2.7.1</version>
<version>2.7.2</version>
<packaging>pom</packaging>
<properties>
<blade.tool.version>2.7.1</blade.tool.version>
<blade.project.version>2.7.1</blade.project.version>
<blade.tool.version>2.7.2</blade.tool.version>
<blade.project.version>2.7.2</blade.project.version>
<java.version>1.8</java.version>
<maven.plugin.version>3.8.1</maven.plugin.version>
<swagger.version>2.9.2</swagger.version>
<swagger.models.version>1.5.21</swagger.models.version>
<knife4j.version>2.0.3</knife4j.version>
<knife4j.version>2.0.4</knife4j.version>
<mybatis.plus.version>3.3.2</mybatis.plus.version>
<protostuff.version>1.6.0</protostuff.version>
<captcha.version>1.6.2</captcha.version>
<easyexcel.version>2.1.6</easyexcel.version>
<easyexcel.version>2.2.6</easyexcel.version>
<mica.auto.version>1.1.0</mica.auto.version>
<alibaba.cloud.version>2.2.1.RELEASE</alibaba.cloud.version>
<spring.boot.admin.version>2.2.3</spring.boot.admin.version>
<spring.boot.admin.version>2.3.0</spring.boot.admin.version>
<spring.boot.version>2.2.7.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR5</spring.cloud.version>
<spring.boot.version>2.2.9.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR7</spring.cloud.version>
<spring.platform.version>Cairo-SR8</spring.platform.version>
<!-- 推荐使用Harbor -->

View File

@ -1,2 +1,2 @@
REGISTER=192.168.0.157/blade
TAG=2.7.1
TAG=2.7.2

View File

@ -1,7 +1,7 @@
version: '3'
services:
nacos:
image: nacos/nacos-server:1.1.3
image: nacos/nacos-server:1.3.2
hostname: "nacos-standalone"
environment:
- MODE=standalone
@ -15,7 +15,7 @@ services:
ipv4_address: 172.30.0.48
sentinel:
image: bladex/sentinel-dashboard:1.5.0
image: bladex/sentinel-dashboard:1.7.2
hostname: "sentinel"
ports:
- 8858:8858