初始代码
This commit is contained in:
22
yunzhupaas-oauth/pom.xml
Normal file
22
yunzhupaas-oauth/pom.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yunzhupaas-java-boot</artifactId>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yunzhupaas-oauth</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>yunzhupaas-oauth-api</module>
|
||||
<module>yunzhupaas-oauth-biz</module>
|
||||
<module>yunzhupaas-oauth-controller</module>
|
||||
<module>yunzhupaas-oauth-entity</module>
|
||||
</modules>
|
||||
|
||||
|
||||
</project>
|
||||
22
yunzhupaas-oauth/yunzhupaas-oauth-api/pom.xml
Normal file
22
yunzhupaas-oauth/yunzhupaas-oauth-api/pom.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yunzhupaas-oauth</artifactId>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yunzhupaas-oauth-api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-oauth-entity</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.yunzhupaas.service;
|
||||
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.model.LoginVO;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface AuthService {
|
||||
ActionResult<LoginVO> login(Map<String, String> parameters) throws LoginException;
|
||||
|
||||
ActionResult kickoutByToken(String... tokens);
|
||||
|
||||
ActionResult kickoutByUserId(String userId, String tenantId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.yunzhupaas.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.model.LoginVO;
|
||||
import com.yunzhupaas.service.AuthService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 内部登录、退出用户工具
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AuthUtil {
|
||||
|
||||
public static AuthService authApi;
|
||||
|
||||
@Autowired
|
||||
public void setAuthApi(AuthService authApi) {
|
||||
AuthUtil.authApi = authApi;
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录临时用户
|
||||
* 此用户已经登录将返回现有用户Token
|
||||
* 未登录将直接使用用户ID进行免密登录返回Token
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param tenantId 租户ID
|
||||
* @return
|
||||
*/
|
||||
public static String loginTempUser(String userId, String tenantId){
|
||||
return loginTempUser(userId, tenantId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录临时用户
|
||||
* 此用户已经登录将返回现有用户Token
|
||||
* 未登录将直接使用用户ID进行免密登录返回Token
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param tenantId 租户ID
|
||||
* @param limited 是否是限制型临时用户(无法登录主系统前端)
|
||||
* @return
|
||||
*/
|
||||
public static String loginTempUser(String userId, String tenantId, boolean limited){
|
||||
Map<String, String> loginInfo = ImmutableMap.of(
|
||||
"grant_type", "tempuser",
|
||||
"token", UserProvider.getInnerAuthToken(),
|
||||
"userId", userId,
|
||||
"tenantId", Optional.ofNullable(tenantId).orElse(StringUtil.NULLSTR),
|
||||
"limited", String.valueOf(limited));
|
||||
String errMsg;
|
||||
ActionResult<LoginVO> result = authApi.login(loginInfo);
|
||||
if(Constants.SUCCESS.equals(result.getCode())){
|
||||
return result.getData().getToken();
|
||||
}
|
||||
log.error("登录临时用户失败: {}", result.getMsg());
|
||||
throw new LoginException(result.getMsg());
|
||||
}
|
||||
|
||||
/**
|
||||
* 踢出用户, 用户将收到Websocket下线通知
|
||||
* 执行流程:认证服务退出用户->用户踢出监听->消息服务发送Websocket推送退出消息
|
||||
* @param tokens
|
||||
*/
|
||||
public static void kickoutByToken(String... tokens){
|
||||
authApi.kickoutByToken(tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* 踢出用户, 用户将收到Websocket下线通知
|
||||
* 执行流程:认证服务退出用户->用户踢出监听->消息服务发送Websocket推送退出消息
|
||||
* @param userId
|
||||
*/
|
||||
public static void kickoutByUserId(String userId){
|
||||
String tenantId = TenantHolder.getDatasourceId();
|
||||
if(tenantId == null) {
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
if (userInfo.getUserId() == null) {
|
||||
throw new RuntimeException("请设置UserInfo");
|
||||
}
|
||||
tenantId = userInfo.getTenantId();
|
||||
}
|
||||
authApi.kickoutByUserId(userId, tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
77
yunzhupaas-oauth/yunzhupaas-oauth-biz/pom.xml
Normal file
77
yunzhupaas-oauth/yunzhupaas-oauth-biz/pom.xml
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yunzhupaas-oauth</artifactId>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yunzhupaas-oauth-biz</artifactId>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-oauth-entity</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-system-biz</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-common-all</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-exception</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.nimbusds</groupId>
|
||||
<artifactId>nimbus-jose-jwt</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-message-biz</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-permission-controller</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-visualdev-portal-biz</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- redis相关依赖包 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-common-security</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,213 @@
|
||||
package com.yunzhupaas.granter;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.config.YunzhupaasOauthConfig;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.consts.LoginTicketStatus;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.model.BaseSystemInfo;
|
||||
import com.yunzhupaas.model.LoginTicketModel;
|
||||
import com.yunzhupaas.model.SocialUnbindModel;
|
||||
import com.yunzhupaas.permission.controller.SocialsUserController;
|
||||
import com.yunzhupaas.permission.model.socails.SocialsUserInfo;
|
||||
import com.yunzhupaas.permission.util.implicit.ImplicitLoginUtil;
|
||||
import com.yunzhupaas.util.ServletUtil;
|
||||
import com.yunzhupaas.util.StringUtil;
|
||||
import com.yunzhupaas.util.TicketUtil;
|
||||
import com.yunzhupaas.util.UserProvider;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.yunzhupaas.granter.ImplicitTokenGranter.GRANT_TYPE;
|
||||
|
||||
@Slf4j
|
||||
@Component(GRANT_TYPE)
|
||||
public class ImplicitTokenGranter extends AbstractTokenGranter {
|
||||
|
||||
public static final String GRANT_TYPE = "implicit";
|
||||
public static final Integer ORDER = 5;
|
||||
private static final String URL_LOGIN = "/Login/implicit/**";
|
||||
|
||||
@Autowired
|
||||
private ImplicitLoginUtil implicitLoginUtil;
|
||||
|
||||
@Autowired
|
||||
private SocialsUserController socialsUserApi;
|
||||
|
||||
@Autowired
|
||||
private YunzhupaasOauthConfig oauthConfig;
|
||||
|
||||
public ImplicitTokenGranter() {
|
||||
super(URL_LOGIN);
|
||||
}
|
||||
|
||||
protected String getGrantType() {
|
||||
return GRANT_TYPE;
|
||||
}
|
||||
|
||||
public ActionResult logout() {
|
||||
return super.logout();
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loginSuccess(UserInfo userInfo, BaseSystemInfo baseSystemInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loginFailure(UserInfo userInfo, BaseSystemInfo baseSystemInfo, Exception e) {
|
||||
super.loginFailure(userInfo, baseSystemInfo, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserDetailKey() {
|
||||
return AuthConsts.USERDETAIL_USER_ID;
|
||||
}
|
||||
|
||||
public ActionResult granter(Map<String, String> map) throws LoginException {
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
String code = req.getParam("code");
|
||||
String source = req.getParam("source");
|
||||
String userAgent = ServletUtil.getUserAgent();
|
||||
if (userAgent.contains("wxwork")) {
|
||||
source = "wechat_enterprise";
|
||||
}
|
||||
if (userAgent.contains("DingTalk")) {
|
||||
source = "dingtalk";
|
||||
}
|
||||
// 授权回调,登录接口,重定向携带token的首页
|
||||
if (StringUtil.isEmpty(source)) {
|
||||
return ActionResult.fail(MsgCode.OA028.get());
|
||||
}
|
||||
// 跳js页面,直接调用授权链接
|
||||
if (StringUtil.isEmpty(code)) {
|
||||
String authLink = implicitLoginUtil.getAuthLink(source);
|
||||
SaHolder.getResponse().redirect(authLink);
|
||||
return null;
|
||||
}
|
||||
String uuid = implicitLoginUtil.loginByCode(source, code, null);
|
||||
// uuid登录
|
||||
return this.loginByUuid(source, uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过第三方用户id登录
|
||||
*
|
||||
* @param source
|
||||
* @param uuid
|
||||
* @return
|
||||
* @throws LoginException
|
||||
*/
|
||||
protected ActionResult loginByUuid(String source, String uuid) throws LoginException {
|
||||
boolean isApp = "APP".equalsIgnoreCase(UserProvider.getDeviceForAgent().getDevice());
|
||||
String url = isApp ? configValueUtil.getAppDomain() : configValueUtil.getFrontDomain();
|
||||
SocialsUserInfo socialsUserInfo = socialsUserApi.getUserInfo(source, uuid, null);
|
||||
if (configValueUtil.isMultiTenancy()) {
|
||||
if (socialsUserInfo == null || CollectionUtil.isEmpty(socialsUserInfo.getTenantUserInfo())) {
|
||||
// 未绑定写入缓存
|
||||
LoginTicketModel ticketModel = (new LoginTicketModel())
|
||||
.setStatus(LoginTicketStatus.UnBindMes.getStatus())
|
||||
.setTicketTimeout(System.currentTimeMillis() + oauthConfig.getTicketTimeout() * 1000);
|
||||
createdTicketState(ticketModel, url, isApp);
|
||||
return ActionResult.success();
|
||||
}
|
||||
if (socialsUserInfo.getTenantUserInfo().size() == 1) {
|
||||
UserInfo userInfo = socialsUserInfo.getUserInfo();
|
||||
// 切换租户
|
||||
switchTenant(userInfo);
|
||||
// 获取系统配置
|
||||
BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
|
||||
// 登录账号
|
||||
String token = super.loginAccount(userInfo, baseSystemInfo);
|
||||
// 返回登录信息
|
||||
String redirectUrl = url + "/sso" + "?token=" + token;
|
||||
if (isApp) {
|
||||
redirectUrl = url + "/pages/login/sso-redirect" + "?token=" + token;
|
||||
}
|
||||
SaHolder.getResponse().redirect(redirectUrl);
|
||||
return ActionResult.success();
|
||||
} else {
|
||||
// 多租户信息写入ticket缓存
|
||||
JSONArray tenantUserInfo = socialsUserInfo.getTenantUserInfo();
|
||||
LoginTicketModel ticketModel = (new LoginTicketModel())
|
||||
.setStatus(LoginTicketStatus.Multitenancy.getStatus()).setValue(tenantUserInfo.toJSONString())
|
||||
.setTicketTimeout(System.currentTimeMillis() + oauthConfig.getTicketTimeout() * 1000);
|
||||
createdTicketState(ticketModel, url, isApp);
|
||||
return ActionResult.success();
|
||||
}
|
||||
} else {
|
||||
if (socialsUserInfo == null || socialsUserInfo.getUserInfo() == null) {
|
||||
// 未绑定写入缓存
|
||||
LoginTicketModel ticketModel = (new LoginTicketModel())
|
||||
.setStatus(LoginTicketStatus.UnBindMes.getStatus())
|
||||
.setTicketTimeout(System.currentTimeMillis() + oauthConfig.getTicketTimeout() * 1000);
|
||||
createdTicketState(ticketModel, url, isApp);
|
||||
return ActionResult.success();
|
||||
}
|
||||
UserInfo userInfo = socialsUserInfo.getUserInfo();
|
||||
// 切换租户
|
||||
switchTenant(userInfo);
|
||||
// 获取系统配置
|
||||
BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
|
||||
// 登录账号
|
||||
String token = super.loginAccount(userInfo, baseSystemInfo);
|
||||
String redirectUrl = url + "/sso" + "?token=" + token;
|
||||
if (isApp) {
|
||||
redirectUrl = url + "/pages/login/sso-redirect" + "?token=" + token;
|
||||
}
|
||||
SaHolder.getResponse().redirect(redirectUrl);
|
||||
return ActionResult.success();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建票据
|
||||
*
|
||||
* @param loginTicketModel
|
||||
* @param url
|
||||
* @param isApp
|
||||
* @return
|
||||
*/
|
||||
private String createdTicketState(LoginTicketModel loginTicketModel, String url, boolean isApp) {
|
||||
String ticket = TicketUtil.createTicket(loginTicketModel, oauthConfig.getTicketTimeout());
|
||||
String MultitenancyUrl = url + "/login?YUNZHUPAAS_TICKET=" + ticket;
|
||||
if (isApp) {
|
||||
MultitenancyUrl = url + "/pages/login/index?YUNZHUPAAS_TICKET=" + ticket;
|
||||
}
|
||||
SaHolder.getResponse().redirect(MultitenancyUrl);
|
||||
return ticket;
|
||||
}
|
||||
|
||||
/**
|
||||
* 未绑定-更新票据缓存
|
||||
*
|
||||
* @param socialType
|
||||
* @param socialUnionid
|
||||
* @param socialName
|
||||
* @return
|
||||
*/
|
||||
protected LoginTicketModel updateTicketUnbind(String socialType, String socialUnionid, String socialName) {
|
||||
LoginTicketModel loginTicketModel = null;
|
||||
SocialUnbindModel obj = new SocialUnbindModel(socialType, socialUnionid, socialName);
|
||||
String ticket = this.getYunzhupaasTicket();
|
||||
if (!ticket.isEmpty()) {
|
||||
loginTicketModel = (new LoginTicketModel()).setStatus(LoginTicketStatus.UnBind.getStatus())
|
||||
.setValue(JSONObject.toJSONString(obj));
|
||||
TicketUtil.updateTicket(ticket, loginTicketModel, (Long) 300L);
|
||||
}
|
||||
return loginTicketModel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
package com.yunzhupaas.granter;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.consts.DeviceType;
|
||||
import com.yunzhupaas.database.util.TenantDataSourceUtil;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.message.entity.UserDeviceEntity;
|
||||
import com.yunzhupaas.message.service.UserDeviceService;
|
||||
import com.yunzhupaas.model.*;
|
||||
import com.yunzhupaas.model.tenant.TenantVO;
|
||||
import com.yunzhupaas.permission.controller.SocialsUserController;
|
||||
import com.yunzhupaas.permission.entity.UserEntity;
|
||||
import com.yunzhupaas.permission.service.UserService;
|
||||
import com.yunzhupaas.util.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.yunzhupaas.granter.PasswordTokenGranter.GRANT_TYPE;
|
||||
import static com.yunzhupaas.util.Constants.ADMIN_KEY;
|
||||
|
||||
/**
|
||||
* 账号密码认证
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @user N
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024/9/17 22:13
|
||||
*/
|
||||
@Slf4j
|
||||
@Component(GRANT_TYPE)
|
||||
public class PasswordTokenGranter extends AbstractTokenGranter {
|
||||
|
||||
public static final String GRANT_TYPE = "password";
|
||||
public static final Integer ORDER = 1;
|
||||
private static final String URL_LOGIN = "";
|
||||
|
||||
public PasswordTokenGranter() {
|
||||
super(URL_LOGIN);
|
||||
}
|
||||
|
||||
public PasswordTokenGranter(String authenticationUrl) {
|
||||
super(authenticationUrl);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private UserService userApi;
|
||||
|
||||
@Autowired
|
||||
private UserDetailsServiceBuilder userDetailsServiceBuilder;
|
||||
|
||||
@Autowired
|
||||
private SocialsUserController socialsUserApi;
|
||||
|
||||
@Autowired
|
||||
private UserDeviceService userDeviceService;
|
||||
|
||||
@Override
|
||||
public ActionResult<LoginVO> granter(Map<String, String> loginParameters) throws LoginException {
|
||||
LoginForm loginForm = JsonUtil.getJsonToBean(loginParameters, LoginForm.class);
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
// 切换租户
|
||||
switchTenant(userInfo);
|
||||
// 获取系统配置
|
||||
BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
|
||||
// 预检信息
|
||||
preAuthenticate(loginForm, userInfo, baseSystemInfo);
|
||||
// 登录账号
|
||||
super.loginAccount(userInfo, baseSystemInfo);
|
||||
// 返回登录信息
|
||||
LoginVO loginResult = getLoginVo(userInfo);
|
||||
return ActionResult.success(loginResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* 可重写实现邮箱、短信、TOTP验证
|
||||
*
|
||||
* @param loginForm
|
||||
* @param sysConfigInfo
|
||||
* @throws LoginException
|
||||
*/
|
||||
protected void preAuthenticate(LoginForm loginForm, UserInfo userInfo, BaseSystemInfo sysConfigInfo)
|
||||
throws LoginException {
|
||||
// 验证密码
|
||||
UserEntity userEntity = userDetailsServiceBuilder.getUserDetailService(AuthConsts.USERDETAIL_ACCOUNT)
|
||||
.loadUserEntity(userInfo);
|
||||
userInfo.setUserId(userEntity.getId());
|
||||
userInfo.setUserName(userEntity.getRealName());
|
||||
UserProvider.setLocalLoginUser(userInfo);
|
||||
// 判断是否开启验证码
|
||||
if (Objects.nonNull(sysConfigInfo) && "1".equals(String.valueOf(sysConfigInfo.getEnableVerificationCode()))) {
|
||||
// 验证验证码
|
||||
String timestamp = String.valueOf(redisUtil.getString(loginForm.getTimestamp()));
|
||||
if (StringUtil.isEmpty(timestamp)) {
|
||||
throw new LoginException(MsgCode.LOG107.get());
|
||||
}
|
||||
if (!loginForm.getCode().equalsIgnoreCase(timestamp)) {
|
||||
throw new LoginException(MsgCode.LOG104.get());
|
||||
}
|
||||
}
|
||||
try {
|
||||
authenticate(loginForm, userEntity, sysConfigInfo);
|
||||
} catch (Exception e) {
|
||||
authenticateFailure(userEntity, sysConfigInfo);
|
||||
throw e;
|
||||
}
|
||||
LoginHolder.setUserEntity(userEntity);
|
||||
}
|
||||
|
||||
protected void authenticate(LoginForm loginForm, UserEntity userEntity, BaseSystemInfo systemInfo)
|
||||
throws LoginException {
|
||||
authenticateLock(userEntity, systemInfo);
|
||||
authenticatePassword(loginForm, userEntity, systemInfo);
|
||||
}
|
||||
|
||||
protected void authenticateLock(UserEntity userEntity, BaseSystemInfo systemInfo) throws LoginException {
|
||||
// 判断当前账号是否被锁定
|
||||
Integer lockMark = userEntity.getEnabledMark();
|
||||
if (Objects.nonNull(lockMark) && lockMark == 2) {
|
||||
// 获取解锁时间
|
||||
Date unlockTime = userEntity.getUnlockTime();
|
||||
// 账号锁定
|
||||
if (systemInfo.getLockType() == 1 || Objects.isNull(unlockTime)) {
|
||||
throw new LoginException(MsgCode.LOG012.get());
|
||||
}
|
||||
// 延迟登陆锁定
|
||||
long millis = System.currentTimeMillis();
|
||||
if (unlockTime.getTime() > millis) {
|
||||
// 转成分钟
|
||||
int time = (int) ((unlockTime.getTime() - millis) / (1000 * 60));
|
||||
throw new LoginException(MsgCode.LOG108.get(time + 1));
|
||||
} else if (unlockTime.getTime() < millis
|
||||
&& userEntity.getLogErrorCount() >= systemInfo.getPasswordErrorsNumber()) {
|
||||
// 已经接触错误时间锁定的话就重置错误次数
|
||||
userEntity.setLogErrorCount(0);
|
||||
userEntity.setEnabledMark(1);
|
||||
userApi.updateById(userEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void authenticatePassword(LoginForm loginForm, UserEntity userEntity, BaseSystemInfo systemInfo)
|
||||
throws LoginException {
|
||||
String inputPwd = loginForm.getPassword();
|
||||
try {
|
||||
// 前端md5后进行aes加密
|
||||
inputPwd = DesUtil.aesOrDecode(inputPwd, false, true);
|
||||
} catch (Exception e) {
|
||||
log.error(MsgCode.OA013.get() + ":{}", inputPwd, e);
|
||||
inputPwd = "";
|
||||
}
|
||||
if (!userEntity.getPassword()
|
||||
.equals(Md5Util.getStringMd5(inputPwd + userEntity.getSecretkey().toLowerCase()))) {
|
||||
throw new LoginException(MsgCode.LOG101.get());
|
||||
}
|
||||
}
|
||||
|
||||
protected void authenticateFailure(UserEntity entity, BaseSystemInfo sysConfigInfo) {
|
||||
if (entity != null) {
|
||||
// 超级管理员特权,不会锁定
|
||||
if (!ADMIN_KEY.equals(entity.getAccount())) {
|
||||
// 判断是否需要锁定账号,哪种锁定方式
|
||||
// 大于2则判断有效
|
||||
Integer errorsNumber = sysConfigInfo.getPasswordErrorsNumber();
|
||||
// 判断是否开启
|
||||
if (errorsNumber != null && errorsNumber > 2) {
|
||||
// 加入错误次数
|
||||
Integer errorCount = entity.getLogErrorCount() != null ? entity.getLogErrorCount() + 1 : 1;
|
||||
entity.setLogErrorCount(errorCount);
|
||||
Integer lockType = sysConfigInfo.getLockType();
|
||||
if (errorCount >= errorsNumber) {
|
||||
entity.setEnabledMark(2);
|
||||
// 如果是延时锁定
|
||||
if (Objects.nonNull(lockType) && lockType == 2) {
|
||||
Integer lockTime = sysConfigInfo.getLockTime();
|
||||
Date date = new Date((System.currentTimeMillis() + (lockTime * 60 * 1000)));
|
||||
entity.setUnlockTime(date);
|
||||
}
|
||||
}
|
||||
if (lockType == 1) {
|
||||
entity.setUnlockTime(null);
|
||||
}
|
||||
userApi.updateById(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void preLogin(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loginSuccess(UserInfo userInfo, BaseSystemInfo baseSystemInfo) {
|
||||
super.loginSuccess(userInfo, baseSystemInfo);
|
||||
// 登录成功绑定第三方
|
||||
if (SaHolder.getRequest().hasParam(AuthConsts.PARAMS_YUNZHUPAAS_TICKET)) {
|
||||
String ticket = SaHolder.getRequest().getParam(AuthConsts.PARAMS_YUNZHUPAAS_TICKET);
|
||||
LoginTicketModel ticketModel = TicketUtil.parseTicket(ticket);
|
||||
if (ticketModel != null) {
|
||||
SocialUnbindModel jsonToBean = JsonUtil.getJsonToBean(ticketModel.getValue(), SocialUnbindModel.class);
|
||||
if (jsonToBean != null) {
|
||||
socialsUserApi.loginAutoBinding(jsonToBean.getSocialType(), jsonToBean.getSocialUnionid(),
|
||||
jsonToBean.getSocialName(),
|
||||
userInfo.getUserId(), userInfo.getTenantId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SaHolder.getRequest().hasParam(AuthConsts.Client_Id)) {
|
||||
String Client_Id = SaHolder.getRequest().getParam(AuthConsts.Client_Id);
|
||||
if (StringUtil.isNotBlank(Client_Id) && !"null".equals(Client_Id)) {
|
||||
UserDeviceEntity userDeviceEntity = userDeviceService.getInfoByClientId(Client_Id);
|
||||
if (userDeviceEntity != null) {
|
||||
userDeviceEntity.setUserId(userInfo.getUserId());
|
||||
userDeviceEntity.setLastModifyTime(DateUtil.getNowDate());
|
||||
userDeviceEntity.setLastModifyUserId(userInfo.getUserId());
|
||||
userDeviceService.update(userDeviceEntity.getId(), userDeviceEntity);
|
||||
} else {
|
||||
userDeviceEntity = new UserDeviceEntity();
|
||||
userDeviceEntity.setId(RandomUtil.uuId());
|
||||
userDeviceEntity.setUserId(userInfo.getUserId());
|
||||
userDeviceEntity.setClientId(Client_Id);
|
||||
userDeviceEntity.setCreatorTime(DateUtil.getNowDate());
|
||||
userDeviceEntity.setCreatorUserId(userInfo.getUserId());
|
||||
userDeviceService.create(userDeviceEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected LoginVO getLoginVo(UserInfo userInfo) {
|
||||
LoginVO loginVO = new LoginVO();
|
||||
loginVO.setTheme(userInfo.getTheme());
|
||||
loginVO.setToken(userInfo.getToken());
|
||||
if (configValueUtil.isMultiTenancy()) {
|
||||
// 删除卫翎信息
|
||||
TenantVO tenantVO = TenantDataSourceUtil.getCacheTenantInfo(userInfo.getTenantId());
|
||||
if (tenantVO != null && tenantVO.getWl_qrcode() != null) {
|
||||
loginVO.setWl_qrcode(tenantVO.getWl_qrcode());
|
||||
tenantVO.setWl_qrcode(null);
|
||||
TenantDataSourceUtil.setTenantInfo(tenantVO);
|
||||
}
|
||||
}
|
||||
return loginVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult logout() {
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
if (userInfo.getUserId() != null) {
|
||||
if ("1".equals(String.valueOf(loginService.getBaseSystemConfig(userInfo.getTenantId()).getSingleLogin()))) {
|
||||
UserProvider.logoutByUserId(userInfo.getUserId(), DeviceType.valueOf(userInfo.getLoginDevice()));
|
||||
} else {
|
||||
UserProvider.logoutByToken(userInfo.getToken());
|
||||
}
|
||||
}
|
||||
return ActionResult.success(MsgCode.OA014.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getGrantType() {
|
||||
return GRANT_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserDetailKey() {
|
||||
return AuthConsts.USERDETAIL_ACCOUNT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.yunzhupaas.granter;
|
||||
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.config.ConfigValueUtil;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.consts.DeviceType;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.model.BaseSystemInfo;
|
||||
import com.yunzhupaas.model.LoginVO;
|
||||
import com.yunzhupaas.util.StringUtil;
|
||||
import com.yunzhupaas.util.UserProvider;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.yunzhupaas.granter.ScanCodeTokenGranter.GRANT_TYPE;
|
||||
|
||||
@Slf4j
|
||||
@Component(GRANT_TYPE)
|
||||
public class ScanCodeTokenGranter extends AbstractTokenGranter {
|
||||
|
||||
public static final String GRANT_TYPE = "scancode";
|
||||
public static final Integer ORDER = 5;
|
||||
private static final String URL_LOGIN = "";
|
||||
@Autowired
|
||||
protected ConfigValueUtil configValueUtil;
|
||||
|
||||
public ScanCodeTokenGranter() {
|
||||
super(URL_LOGIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param loginParameters {userId, tenantId}
|
||||
* @return
|
||||
* @throws LoginException
|
||||
*/
|
||||
@Override
|
||||
public ActionResult granter(Map<String, String> loginParameters) throws LoginException {
|
||||
String token = loginParameters.get("token");
|
||||
// 验证token是否有效
|
||||
UserInfo userInfo = UserProvider.getUser(token);
|
||||
if (configValueUtil.isMultiTenancy()){
|
||||
userInfo.setUserAccount(userInfo.getTenantId()+"@"+userInfo.getUserAccount());
|
||||
}
|
||||
//切换租户
|
||||
switchTenant(userInfo);
|
||||
//获取系统配置
|
||||
BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
|
||||
//登录账号
|
||||
super.loginAccount(userInfo, baseSystemInfo);
|
||||
//返回登录信息
|
||||
LoginVO loginResult = getLoginVo(userInfo);
|
||||
return ActionResult.success(loginResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
|
||||
protected LoginVO getLoginVo(UserInfo userInfo) {
|
||||
LoginVO loginVO = new LoginVO();
|
||||
loginVO.setTheme(userInfo.getTheme());
|
||||
loginVO.setToken(userInfo.getToken());
|
||||
return loginVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult logout() {
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
if (userInfo.getUserId() != null) {
|
||||
if ("1".equals(String.valueOf(loginService.getBaseSystemConfig(userInfo.getTenantId()).getSingleLogin()))) {
|
||||
UserProvider.logoutByUserId(userInfo.getUserId(), DeviceType.valueOf(userInfo.getLoginDevice()));
|
||||
} else {
|
||||
UserProvider.logoutByToken(userInfo.getToken());
|
||||
}
|
||||
}
|
||||
return ActionResult.success(MsgCode.OA014.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getGrantType() {
|
||||
return GRANT_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserDetailKey() {
|
||||
return AuthConsts.USERDETAIL_USER_ID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
package com.yunzhupaas.granter;
|
||||
|
||||
import cn.dev33.satoken.context.SaHolder;
|
||||
import cn.dev33.satoken.context.model.SaRequest;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.consts.LoginTicketStatus;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.model.BaseSystemInfo;
|
||||
import com.yunzhupaas.model.LoginTicketModel;
|
||||
import com.yunzhupaas.model.SocialUnbindModel;
|
||||
import com.yunzhupaas.model.LoginVO;
|
||||
import com.yunzhupaas.permission.controller.SocialsUserController;
|
||||
import com.yunzhupaas.permission.model.socails.SocialsUserInfo;
|
||||
import com.yunzhupaas.service.impl.UserDetailsByUserIdServiceImpl;
|
||||
import com.yunzhupaas.util.ServletUtil;
|
||||
import com.yunzhupaas.util.StringUtil;
|
||||
import com.yunzhupaas.util.TicketUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.yunzhupaas.granter.SocialsTokenGranter.GRANT_TYPE;
|
||||
|
||||
@Slf4j
|
||||
@Component(GRANT_TYPE)
|
||||
public class SocialsTokenGranter extends AbstractTokenGranter {
|
||||
|
||||
public static final String GRANT_TYPE = "socials";
|
||||
public static final Integer ORDER = 5;
|
||||
private static final String URL_LOGIN = "/Login/socials/**";
|
||||
|
||||
@Autowired
|
||||
private SocialsUserController socialsUserApi;
|
||||
|
||||
public SocialsTokenGranter() {
|
||||
super(URL_LOGIN);
|
||||
}
|
||||
|
||||
protected String getGrantType() {
|
||||
return GRANT_TYPE;
|
||||
}
|
||||
|
||||
public ActionResult granter(Map<String, String> map) throws LoginException {
|
||||
SaRequest req = SaHolder.getRequest();
|
||||
String code = req.getParam("code");
|
||||
String state = req.getParam("state");
|
||||
String source = req.getParam("source");
|
||||
String uuid = req.getParam("uuid");
|
||||
if (StringUtil.isEmpty(code)) {
|
||||
code = req.getParam("authCode") != null ? req.getParam("authCode") : req.getParam("auth_code");
|
||||
}
|
||||
// 是否是微信qq唤醒或者小程序登录
|
||||
if (StringUtil.isNotEmpty(uuid)) {
|
||||
try {
|
||||
return loginByCode(source, code, null, uuid, null);
|
||||
} catch (Exception e) {
|
||||
// 更新登录结果
|
||||
outError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtil.isEmpty(req.getParam(AuthConsts.PARAMS_YUNZHUPAAS_TICKET))) {
|
||||
// 租户列表登陆标识
|
||||
boolean tenantLogin = StringUtil.isEmpty(req.getParam("tenantLogin")) ? false
|
||||
: req.getParam("tenantLogin").equals("true") ? true : false;
|
||||
// 租户列表点击登录调用
|
||||
if (!tenantLogin) {
|
||||
// 绑定
|
||||
socialsBinding(req, code, state, source);
|
||||
return null;
|
||||
} else {// 租户列表点击登录
|
||||
LoginVO loginVO = tenantLogin(req);
|
||||
return ActionResult.success(MsgCode.OA015.get(), loginVO);
|
||||
}
|
||||
} else {
|
||||
// 票据登陆
|
||||
if (!isValidYunzhupaasTicket()) {
|
||||
outError(MsgCode.OA016.get());
|
||||
return null;
|
||||
}
|
||||
// 接受CODE 进行登录
|
||||
if (SaFoxUtil.isNotEmpty(code)) {
|
||||
try {
|
||||
String socialName = req.getParam("socialName");
|
||||
ActionResult actionResult = loginByCode(source, code, state, null, socialName);
|
||||
if (400 == actionResult.getCode() || "wechat_applets".equals(req.getParam("source"))) {
|
||||
return actionResult;
|
||||
}
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
// 更新登录结果
|
||||
outError(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 租户列表登录
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024/9/21
|
||||
*/
|
||||
private LoginVO tenantLogin(SaRequest req) throws LoginException {
|
||||
String userId = req.getParam("userId");
|
||||
String account = req.getParam("account");
|
||||
String tenantId = req.getParam("tenantId");
|
||||
UserInfo userInfo = new UserInfo();
|
||||
userInfo.setUserId(userId);
|
||||
userInfo.setTenantId(tenantId);
|
||||
userInfo.setUserAccount(tenantId + "@" + account);
|
||||
// 切换租户
|
||||
switchTenant(userInfo);
|
||||
// 获取系统配置
|
||||
BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
|
||||
// 登录账号
|
||||
super.loginAccount(userInfo, baseSystemInfo);
|
||||
// 返回登录信息
|
||||
LoginVO loginVo = getLoginVo(userInfo);
|
||||
return loginVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方绑定
|
||||
*/
|
||||
private void socialsBinding(SaRequest req, String code, String state, String source) {
|
||||
String userId = req.getParam("userId");
|
||||
String tenantId = req.getParam("tenantId");
|
||||
PrintWriter out = null;
|
||||
try {
|
||||
HttpServletResponse response = ServletUtil.getResponse();
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setHeader("content-type", "text/html;charset=utf-8");
|
||||
out = response.getWriter();
|
||||
JSONObject binding = socialsUserApi.binding(source, userId, tenantId, code, state);
|
||||
out.print(
|
||||
"<script>\n" +
|
||||
"window.opener.postMessage(\'" + binding.toJSONString() + "\', '*');\n" +
|
||||
"window.open('','_self','');\n" +
|
||||
"window.close();\n" + "</script>");
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public ActionResult logout() {
|
||||
return super.logout();
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loginSuccess(UserInfo userInfo, BaseSystemInfo baseSystemInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loginFailure(UserInfo userInfo, BaseSystemInfo baseSystemInfo, Exception e) {
|
||||
super.loginFailure(userInfo, baseSystemInfo, e);
|
||||
}
|
||||
|
||||
protected void outError(String message) {
|
||||
updateTicketError(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserDetailKey() {
|
||||
return AuthConsts.USERDETAIL_USER_ID;
|
||||
}
|
||||
|
||||
protected LoginTicketModel updateTicketUnbind(String socialType, String socialUnionid, String socialName) {
|
||||
LoginTicketModel loginTicketModel = null;
|
||||
SocialUnbindModel obj = new SocialUnbindModel(socialType, socialUnionid, socialName);
|
||||
String ticket = this.getYunzhupaasTicket();
|
||||
if (!ticket.isEmpty()) {
|
||||
loginTicketModel = (new LoginTicketModel()).setStatus(LoginTicketStatus.UnBind.getStatus())
|
||||
.setValue(JSONObject.toJSONString(obj));
|
||||
TicketUtil.updateTicket(ticket, loginTicketModel, (Long) 300L);
|
||||
}
|
||||
return loginTicketModel;
|
||||
}
|
||||
|
||||
protected LoginTicketModel updateTicketMultitenancy(JSONArray jsonArray) {
|
||||
LoginTicketModel loginTicketModel = null;
|
||||
String ticket = this.getYunzhupaasTicket();
|
||||
if (!ticket.isEmpty()) {
|
||||
loginTicketModel = (new LoginTicketModel()).setStatus(LoginTicketStatus.Multitenancy.getStatus())
|
||||
.setValue(jsonArray.toJSONString());
|
||||
TicketUtil.updateTicket(ticket, loginTicketModel, (Long) null);
|
||||
}
|
||||
return loginTicketModel;
|
||||
}
|
||||
|
||||
protected LoginTicketModel updateTicketSuccessReturn(UserInfo userInfo) {
|
||||
LoginTicketModel loginTicketModel = null;
|
||||
String ticket = getYunzhupaasTicket();
|
||||
if (!ticket.isEmpty()) {
|
||||
loginTicketModel = new LoginTicketModel()
|
||||
.setStatus(LoginTicketStatus.Success.getStatus())
|
||||
.setValue(StpUtil.getTokenValueNotCut())
|
||||
.setTheme(userInfo.getTheme());
|
||||
TicketUtil.updateTicket(ticket, loginTicketModel, null);
|
||||
}
|
||||
return loginTicketModel;
|
||||
}
|
||||
|
||||
protected LoginVO getLoginVo(UserInfo userInfo) {
|
||||
LoginVO loginVO = new LoginVO();
|
||||
loginVO.setTheme(userInfo.getTheme());
|
||||
loginVO.setToken(userInfo.getToken());
|
||||
return loginVO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序登录微信授权
|
||||
* app微信,qq唤醒
|
||||
*
|
||||
* @param code
|
||||
* @throws LoginException
|
||||
*/
|
||||
protected ActionResult loginByCode(String source, String code, String state, String uuid, String socialName)
|
||||
throws LoginException {
|
||||
log.debug("Auth2 Code: {}", code);
|
||||
SocialsUserInfo socialsUserInfo = null;
|
||||
if (StringUtil.isNotEmpty(code)) {
|
||||
socialsUserInfo = socialsUserApi.getSocialsUserInfo(source, code, state);
|
||||
} else if (StringUtil.isNotEmpty(uuid)) {// 微信和qq唤醒
|
||||
socialsUserInfo = socialsUserApi.getUserInfo(source, uuid, state);
|
||||
if (StringUtil.isEmpty(socialsUserInfo.getSocialName()) && StringUtil.isNotEmpty(socialName)) {
|
||||
socialsUserInfo.setSocialName(socialName);// 小程序名称前端传递
|
||||
}
|
||||
}
|
||||
if (configValueUtil.isMultiTenancy()) {
|
||||
if (socialsUserInfo == null || CollectionUtil.isEmpty(socialsUserInfo.getTenantUserInfo())) {
|
||||
updateTicketUnbind(source, socialsUserInfo.getSocialUnionid(), socialsUserInfo.getSocialName());// 第三方未绑定账号!
|
||||
return ActionResult.fail(MsgCode.OA017.get());
|
||||
}
|
||||
if (socialsUserInfo.getTenantUserInfo().size() == 1) {
|
||||
UserInfo userInfo = socialsUserInfo.getUserInfo();
|
||||
// 切换租户
|
||||
switchTenant(userInfo);
|
||||
// 获取系统配置
|
||||
BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
|
||||
// 登录账号
|
||||
super.loginAccount(userInfo, baseSystemInfo);
|
||||
// 返回登录信息
|
||||
LoginTicketModel loginTicketModel = updateTicketSuccessReturn(userInfo);
|
||||
return ActionResult.success(loginTicketModel);
|
||||
} else {
|
||||
JSONArray tenantUserInfo = socialsUserInfo.getTenantUserInfo();
|
||||
LoginTicketModel loginTicketModel = updateTicketMultitenancy(tenantUserInfo);
|
||||
return ActionResult.success(loginTicketModel);
|
||||
}
|
||||
} else {
|
||||
if (socialsUserInfo == null || socialsUserInfo.getUserInfo() == null) {
|
||||
updateTicketUnbind(source, socialsUserInfo.getSocialUnionid(), socialsUserInfo.getSocialName());// 第三方未绑定账号!
|
||||
return ActionResult.fail(MsgCode.OA017.get());
|
||||
}
|
||||
UserInfo userInfo = socialsUserInfo.getUserInfo();
|
||||
// 切换租户
|
||||
switchTenant(userInfo);
|
||||
// 获取系统配置
|
||||
BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
|
||||
// 登录账号
|
||||
super.loginAccount(userInfo, baseSystemInfo);
|
||||
LoginTicketModel loginTicketModel = updateTicketSuccessReturn(userInfo);
|
||||
return ActionResult.success(loginTicketModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.yunzhupaas.granter;
|
||||
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.consts.DeviceType;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.model.BaseSystemInfo;
|
||||
import com.yunzhupaas.model.LoginVO;
|
||||
import com.yunzhupaas.util.UserProvider;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.yunzhupaas.granter.TempUserTokenGranter.GRANT_TYPE;
|
||||
|
||||
|
||||
/**
|
||||
* 临时用户认证
|
||||
* @user N
|
||||
* @author 云筑产品开发平台组
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024/9/16 21:25
|
||||
*/
|
||||
@Slf4j
|
||||
@Component(GRANT_TYPE)
|
||||
public class TempUserTokenGranter extends AbstractTokenGranter{
|
||||
|
||||
public static final String GRANT_TYPE = "tempuser";
|
||||
public static final Integer ORDER = 4;
|
||||
private static final String URL_LOGIN = "";
|
||||
|
||||
|
||||
public TempUserTokenGranter(){
|
||||
super(URL_LOGIN);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param loginParameters {userId, tenantId}
|
||||
* @return
|
||||
* @throws LoginException
|
||||
*/
|
||||
@Override
|
||||
public ActionResult granter(Map<String, String> loginParameters) throws LoginException {
|
||||
String token = loginParameters.get("token");
|
||||
//验证是否由内部发起
|
||||
if(!UserProvider.isValidInnerToken(token)){
|
||||
throw new LoginException(MsgCode.OA018.get());
|
||||
}
|
||||
String userId = loginParameters.get("userId");
|
||||
String tenantId = loginParameters.get("tenantId");
|
||||
boolean limited = Boolean.valueOf(loginParameters.get("limited"));
|
||||
String device = limited?DeviceType.TEMPUSERLIMITED.getDevice():DeviceType.TEMPUSER.getDevice();
|
||||
//尝试获取已经登录的用户信息
|
||||
UserInfo userInfo;
|
||||
if(limited){
|
||||
//只获取限制类型的TOKEN
|
||||
userInfo = UserProvider.getUser(userId, tenantId, Arrays.asList(DeviceType.TEMPUSERLIMITED.getDevice()), null);
|
||||
}else{
|
||||
//排除限制类型的TOKEN
|
||||
userInfo = UserProvider.getUser(userId, tenantId, null, Arrays.asList(DeviceType.TEMPUSERLIMITED.getDevice()));
|
||||
}
|
||||
if(userInfo.getUserId() != null){
|
||||
return ActionResult.success(getLoginVo(userInfo));
|
||||
}
|
||||
userInfo = UserProvider.getUser();
|
||||
userInfo.setUserAccount(tenantId);
|
||||
userInfo.setUserId(userId);
|
||||
//切换租户
|
||||
switchTenant(userInfo);
|
||||
//获取系统配置
|
||||
BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
|
||||
//先设置用户类型
|
||||
userInfo.setLoginDevice(device);
|
||||
//登录账号
|
||||
super.loginAccount(userInfo, baseSystemInfo);
|
||||
//返回登录信息
|
||||
LoginVO loginResult = getLoginVo(userInfo);
|
||||
return ActionResult.success(loginResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void preLogin(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void login(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
|
||||
UserProvider.loginNoRequest(userInfo, this.getLoginModel(userInfo, baseSystemInfo));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loginSuccess(UserInfo userInfo, BaseSystemInfo baseSystemInfo) {
|
||||
super.loginSuccess(userInfo, baseSystemInfo);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DeviceType getDeviceType() {
|
||||
return DeviceType.TEMPUSER;
|
||||
}
|
||||
|
||||
protected LoginVO getLoginVo(UserInfo userInfo){
|
||||
LoginVO loginVO = new LoginVO();
|
||||
loginVO.setTheme(userInfo.getTheme());
|
||||
loginVO.setToken(userInfo.getToken());
|
||||
return loginVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult logout() {
|
||||
//非临时用户不注销
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
if(UserProvider.isTempUser(userInfo)){
|
||||
UserProvider.logoutByToken(userInfo.getToken());
|
||||
}
|
||||
return ActionResult.success(MsgCode.OA014.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getGrantType() {
|
||||
return GRANT_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUserDetailKey() {
|
||||
return AuthConsts.USERDETAIL_USER_ID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.yunzhupaas.granter;
|
||||
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.database.util.TenantDataSourceUtil;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.model.BaseSystemInfo;
|
||||
import com.yunzhupaas.model.LoginForm;
|
||||
import com.yunzhupaas.model.LoginVO;
|
||||
import com.yunzhupaas.permission.entity.UserEntity;
|
||||
import com.yunzhupaas.util.JsonUtil;
|
||||
import com.yunzhupaas.util.LoginHolder;
|
||||
import com.yunzhupaas.util.UserProvider;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.yunzhupaas.granter.YunzhupaasOfficialTokenGranter.GRANT_TYPE;
|
||||
|
||||
/**
|
||||
* YUNZHUPAAS官网专用短信认证
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @user N
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024/9/17 22:13
|
||||
*/
|
||||
@Slf4j
|
||||
@Component(GRANT_TYPE)
|
||||
public class YunzhupaasOfficialTokenGranter extends PasswordTokenGranter {
|
||||
|
||||
public static final String GRANT_TYPE = "official";
|
||||
|
||||
@Autowired
|
||||
private UserDetailsServiceBuilder userDetailsServiceBuilder;
|
||||
|
||||
@Override
|
||||
public ActionResult granter(Map<String, String> loginParameters) throws LoginException {
|
||||
LoginForm loginForm = JsonUtil.getJsonToBean(loginParameters, LoginForm.class);
|
||||
// 校验短信验证码
|
||||
TenantDataSourceUtil.checkOfficialSmsCode(loginForm.getAccount(), loginForm.getCode(), 1);
|
||||
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
// 切换租户
|
||||
switchTenant(userInfo);
|
||||
// 获取系统配置
|
||||
BaseSystemInfo baseSystemInfo = getSysconfig(userInfo);
|
||||
// 预检信息
|
||||
preAuthenticate(loginForm, userInfo, baseSystemInfo);
|
||||
// 登录账号
|
||||
super.loginAccount(userInfo, baseSystemInfo);
|
||||
// 返回登录信息
|
||||
LoginVO loginResult = getLoginVo(userInfo);
|
||||
return ActionResult.success(loginResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 可重写实现邮箱、短信、TOTP验证
|
||||
*
|
||||
* @param loginForm
|
||||
* @param sysConfigInfo
|
||||
* @throws LoginException
|
||||
*/
|
||||
protected void preAuthenticate(LoginForm loginForm, UserInfo userInfo, BaseSystemInfo sysConfigInfo)
|
||||
throws LoginException {
|
||||
// 验证密码
|
||||
UserEntity userEntity = userDetailsServiceBuilder.getUserDetailService(AuthConsts.USERDETAIL_ACCOUNT)
|
||||
.loadUserEntity(userInfo);
|
||||
try {
|
||||
authenticateLock(userEntity, sysConfigInfo);
|
||||
} catch (Exception e) {
|
||||
authenticateFailure(userEntity, sysConfigInfo);
|
||||
throw e;
|
||||
}
|
||||
LoginHolder.setUserEntity(userEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getGrantType() {
|
||||
return GRANT_TYPE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package com.yunzhupaas.listener;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.lock.LockInfo;
|
||||
import com.baomidou.lock.LockTemplate;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.base.model.module.ModuleModel;
|
||||
import com.yunzhupaas.constant.EventConst;
|
||||
import com.yunzhupaas.event.ProjectEventListener;
|
||||
import com.yunzhupaas.module.ProjectEventInstance;
|
||||
import com.yunzhupaas.permission.entity.RoleEntity;
|
||||
import com.yunzhupaas.permission.model.authorize.AuthorizeVO;
|
||||
import com.yunzhupaas.permission.service.RoleService;
|
||||
import com.yunzhupaas.permissions.PermissionInterfaceImpl;
|
||||
import com.yunzhupaas.util.JsonUtil;
|
||||
import com.yunzhupaas.util.StringUtil;
|
||||
import com.yunzhupaas.util.UserProvider;
|
||||
import com.yunzhupaas.workflow.service.TemplateApi;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.yunzhupaas.util.Constants.ADMIN_KEY;
|
||||
|
||||
/**
|
||||
* 接口权限初始化
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class InterfacePermissionListener {
|
||||
|
||||
@Autowired
|
||||
private RoleService roleApi;
|
||||
@Autowired
|
||||
private LockTemplate lockTemplate;
|
||||
@Autowired
|
||||
private TemplateApi templateApi;
|
||||
|
||||
@ProjectEventListener(channel = EventConst.EVENT_INIT_LOGIN_PERMISSION)
|
||||
public void initPermission(ProjectEventInstance eventInstance) {
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
//远程事件
|
||||
// AuthorizeVO authorizeVO = ((JSONObject)eventInstance.getSource()).toJavaObject(AuthorizeVO.class);
|
||||
//本地事件
|
||||
AuthorizeVO authorizeVO = (AuthorizeVO) eventInstance.getSource();
|
||||
initSecurityAuthorities(authorizeVO, userInfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化接口鉴权用的账号权限
|
||||
* 本接口插入权限缓存, SaInterfaceImpl中框架鉴权时动态调用获取权限列表
|
||||
*
|
||||
* @param authorizeModel
|
||||
* @param userInfo
|
||||
*/
|
||||
private void initSecurityAuthorities(AuthorizeVO authorizeModel, UserInfo userInfo) {
|
||||
//接口权限
|
||||
Set<String> authorityList = new HashSet<>();
|
||||
Set<String> roleAuthorityList = new HashSet<>();
|
||||
Map<String, ModuleModel> moduleModelMap = new LinkedHashMap<>();
|
||||
Map<String, String> flowFormMap = new HashMap<>();
|
||||
Map<String, String> allFlowFormMap = templateApi.getFlowFormMap();
|
||||
|
||||
Map<String, List<Map<String, Object>>> columnsMap = new HashMap<>();
|
||||
Map<String, List<Map<String, Object>>> formMap = new HashMap<>();
|
||||
for (ModuleModel moduleModel : authorizeModel.getModuleList()) {
|
||||
// 添加菜单权限
|
||||
// 添加菜单ID, 代码生成用
|
||||
authorityList.add(moduleModel.getId());
|
||||
// 添加菜单编码
|
||||
authorityList.add(moduleModel.getEnCode());
|
||||
moduleModelMap.put(moduleModel.getId(), moduleModel);
|
||||
//功能菜单 3:功能菜单, 9: 流程菜单
|
||||
if (moduleModel.getType() == 3 || moduleModel.getType() == 9 || moduleModel.getType() == 10) {
|
||||
JSONObject propertyJSON = JSONObject.parseObject(Optional.of(moduleModel.getPropertyJson()).orElse("{}"));
|
||||
//{"iconBackgroundColor":"","isTree":0,"moduleId":"395851986114733317"}
|
||||
String moduleId = propertyJSON.getString("moduleId");
|
||||
if (!StringUtil.isEmpty(moduleId)) {
|
||||
authorityList.add(moduleId);
|
||||
// 流程菜单 拥有流程菜单权限, 直接赋予流程下第一个表单的权限
|
||||
if (moduleModel.getType() == 9) {
|
||||
// 表单编码
|
||||
String formId = flowFormMap.get(moduleId);
|
||||
if (formId == null) {
|
||||
formId = allFlowFormMap.get(moduleId);
|
||||
}
|
||||
if (StringUtil.isNotEmpty(formId)) {
|
||||
flowFormMap.put(moduleId, formId);
|
||||
authorityList.add(formId);
|
||||
} else {
|
||||
log.error("初始化流程菜单权限失败, 流程表单不存在:" + moduleModel.getFullName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//按钮权限 菜单编码::按钮编码
|
||||
authorizeModel.getButtonList().forEach(t -> {
|
||||
ModuleModel m = moduleModelMap.get(t.getModuleId());
|
||||
if (m != null) {
|
||||
authorityList.add(m.getEnCode() + "::" + t.getEnCode());
|
||||
//功能菜单的按钮权限 3:功能菜单, 9: 流程菜单
|
||||
if (m.getType() == 3 || m.getType() == 9) {
|
||||
JSONObject propertyJSON = JSONObject.parseObject(Optional.of(m.getPropertyJson()).orElse("{}"));
|
||||
//{"iconBackgroundColor":"","isTree":0,"moduleId":"395851986114733317"}
|
||||
String moduleId = propertyJSON.getString("moduleId");
|
||||
if (!StringUtil.isEmpty(moduleId)) {
|
||||
authorityList.add(moduleId + "::" + t.getEnCode());
|
||||
// 流程菜单, 直接赋予流程下第一个表单的对应流程按钮权限
|
||||
if (m.getType() == 9) {
|
||||
// 表单编码
|
||||
String formId = flowFormMap.get(moduleId);
|
||||
if (StringUtil.isNotEmpty(formId)) {
|
||||
authorityList.add(formId + "::" + t.getEnCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
//列表权限 菜单编码::列表编码
|
||||
authorizeModel.getColumnList().forEach(t -> {
|
||||
ModuleModel m = moduleModelMap.get(t.getModuleId());
|
||||
if (m != null) {
|
||||
authorityList.add(m.getEnCode() + "::" + t.getEnCode());
|
||||
}
|
||||
List<Map<String, Object>> list;
|
||||
if (columnsMap.get(t.getModuleId()) == null) {
|
||||
list = new ArrayList<>();
|
||||
list.add(JsonUtil.entityToMap(t));
|
||||
columnsMap.put(t.getModuleId(), list);
|
||||
} else {
|
||||
list = columnsMap.get(t.getModuleId());
|
||||
list.add(JsonUtil.entityToMap(t));
|
||||
columnsMap.put(t.getModuleId(), list);
|
||||
}
|
||||
});
|
||||
//表单权限 菜单编码::表单编码
|
||||
authorizeModel.getFormsList().forEach(t -> {
|
||||
ModuleModel m = moduleModelMap.get(t.getModuleId());
|
||||
if (m != null) {
|
||||
authorityList.add(m.getEnCode() + "::" + t.getEnCode());
|
||||
}
|
||||
List<Map<String, Object>> list;
|
||||
if (formMap.get(t.getModuleId()) == null) {
|
||||
list = new ArrayList<>();
|
||||
list.add(JsonUtil.entityToMap(t));
|
||||
formMap.put(t.getModuleId(), list);
|
||||
} else {
|
||||
list = formMap.get(t.getModuleId());
|
||||
list.add(JsonUtil.entityToMap(t));
|
||||
formMap.put(t.getModuleId(), list);
|
||||
}
|
||||
});
|
||||
|
||||
if (userInfo.getRoleIds() != null && !userInfo.getRoleIds().isEmpty() || userInfo.getIsAdministrator()) {
|
||||
List<RoleEntity> roles;
|
||||
if (userInfo.getIsAdministrator()) {
|
||||
roles = roleApi.getList(false);
|
||||
} else {
|
||||
roles = roleApi.getListByIds(userInfo.getRoleIds(), null, false);
|
||||
}
|
||||
roleAuthorityList = roles.stream().filter(r -> r.getEnabledMark().equals(1)).map(r -> "ROLE_" + r.getEnCode()).collect(Collectors.toSet());
|
||||
|
||||
}
|
||||
|
||||
//管理员都是用同一个缓存, 普通账号使用账号名,
|
||||
//权限列表:authorize_:租户_authorize_authorize_(admin|账号)
|
||||
//角色列表:authorize_:租户_authorize_role_(admin|账号)
|
||||
String account = userInfo.getIsAdministrator() ? ADMIN_KEY : userInfo.getUserId();
|
||||
LockInfo lockInstance = null;
|
||||
try {
|
||||
if (!authorityList.isEmpty() || !roleAuthorityList.isEmpty()) {
|
||||
String loginId = UserProvider.splicingLoginId(account);
|
||||
// 等待其他服务初始化权限完毕
|
||||
// lockInstance = lockTemplate.lock(RedisConst.REDIS_LOCK4J_PREFIX + ModuleName.OAUTH_SERVER_NAME + loginId, 10000L, 10000L);
|
||||
// if(lockInstance != null) {
|
||||
if (!authorityList.isEmpty()) {
|
||||
// 添加旧权限
|
||||
authorityList.addAll(StpUtil.getPermissionList(loginId));
|
||||
PermissionInterfaceImpl.setAuthorityList(account, authorityList, null);
|
||||
}
|
||||
if (!roleAuthorityList.isEmpty()) {
|
||||
// 添加旧权限
|
||||
roleAuthorityList.addAll(StpUtil.getRoleList(loginId));
|
||||
PermissionInterfaceImpl.setRoleList(account, roleAuthorityList, null);
|
||||
}
|
||||
|
||||
if (!columnsMap.isEmpty()) {
|
||||
PermissionInterfaceImpl.setColumnMap(account, columnsMap, null);
|
||||
}
|
||||
|
||||
if (!formMap.isEmpty()) {
|
||||
PermissionInterfaceImpl.setFormMap(account, formMap, null);
|
||||
}
|
||||
|
||||
// }
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("初始化接口权限失败", e);
|
||||
} finally {
|
||||
// if(lockInstance != null) {
|
||||
// lockTemplate.releaseLock(lockInstance);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.yunzhupaas.listener;
|
||||
|
||||
import cn.dev33.satoken.listener.SaTokenListenerForSimple;
|
||||
import cn.dev33.satoken.stp.SaLoginModel;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.consts.DeviceType;
|
||||
import com.yunzhupaas.message.service.MessageService;
|
||||
import com.yunzhupaas.permission.entity.UserEntity;
|
||||
import com.yunzhupaas.permission.service.UserService;
|
||||
import com.yunzhupaas.service.LogService;
|
||||
import com.yunzhupaas.util.DateUtil;
|
||||
import com.yunzhupaas.util.IpUtil;
|
||||
import com.yunzhupaas.util.LoginHolder;
|
||||
import com.yunzhupaas.util.UserProvider;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LoginListener extends SaTokenListenerForSimple {
|
||||
|
||||
|
||||
@Autowired
|
||||
private MessageService messageApi;
|
||||
@Autowired
|
||||
private UserService userApi;
|
||||
|
||||
@Override
|
||||
public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
|
||||
println( MsgCode.OA001.get()+":{}, "+MsgCode.OA002.get()+":{}, "+MsgCode.OA003.get()+":{}", loginId, loginType, tokenValue);
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
//临时用户登录不记录
|
||||
if(!UserProvider.isTempUser(userInfo)) {
|
||||
|
||||
UserEntity entity = LoginHolder.getUserEntity();
|
||||
entity.setLogErrorCount(0);
|
||||
entity.setUnlockTime(null);
|
||||
entity.setEnabledMark(1);
|
||||
entity.setPrevLogIp(IpUtil.getIpAddr());
|
||||
entity.setPrevLogTime(DateUtil.getNowDate());
|
||||
entity.setLastLogIp(IpUtil.getIpAddr());
|
||||
entity.setLastLogTime(DateUtil.getNowDate());
|
||||
entity.setLogSuccessCount(entity.getLogSuccessCount() != null ? entity.getLogSuccessCount() + 1 : 1);
|
||||
|
||||
userApi.updateById(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doLogout(String loginType, Object loginId, String tokenValue) {
|
||||
println(MsgCode.OA004.get()+":{}, "+MsgCode.OA002.get()+":{}, "+MsgCode.OA003.get()+":{}", loginId, loginType, tokenValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doKickout(String loginType, Object loginId, String tokenValue) {
|
||||
println(MsgCode.OA005.get()+":{}, "+MsgCode.OA002.get()+":{}, "+MsgCode.OA003.get()+":{}", loginId, loginType, tokenValue);
|
||||
messageApi.logoutWebsocketByToken(tokenValue, null);
|
||||
//删除用户信息缓存, 保留Token状态记录等待自动过期, 如果用户不在线下次打开浏览器会提示被踢下线
|
||||
StpUtil.getTokenSessionByToken(tokenValue).logout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doReplaced(String loginType, Object loginId, String tokenValue) {
|
||||
println(MsgCode.OA006.get()+":{}, "+MsgCode.OA002.get()+":{}, "+MsgCode.OA003.get()+":{}", loginId, loginType, tokenValue);
|
||||
messageApi.logoutWebsocketByToken(tokenValue, null);
|
||||
StpUtil.getTokenSessionByToken(tokenValue).logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印指定字符串
|
||||
* @param str 字符串
|
||||
*/
|
||||
public void println(String str, Object... params) {
|
||||
if(log.isDebugEnabled()) {
|
||||
log.debug(str, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.yunzhupaas.listener;
|
||||
|
||||
import com.yunzhupaas.config.ConfigValueUtil;
|
||||
import com.yunzhupaas.util.RedisUtil;
|
||||
import com.yunzhupaas.util.context.SpringContext;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @version V3.1.0
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024/3/16 8:49
|
||||
*/
|
||||
@Component
|
||||
public class YunzhupaasListener implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
private ConfigValueUtil configValueUtil;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
configValueUtil = SpringContext.getBean(ConfigValueUtil.class);
|
||||
if ("false".equals(configValueUtil.getTestVersion())) {
|
||||
RedisUtil redisUtil = SpringContext.getBean(RedisUtil.class);
|
||||
redisUtil.removeAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.yunzhupaas.service.impl;
|
||||
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.config.ConfigValueUtil;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.exception.TenantDatabaseException;
|
||||
import com.yunzhupaas.exception.TenantInvalidException;
|
||||
import com.yunzhupaas.granter.TokenGranter;
|
||||
import com.yunzhupaas.granter.TokenGranterBuilder;
|
||||
import com.yunzhupaas.model.LoginVO;
|
||||
import com.yunzhupaas.service.AuthService;
|
||||
import com.yunzhupaas.service.LogService;
|
||||
import com.yunzhupaas.util.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 登录与退出服务 其他服务调用
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AuthServiceImpl implements AuthService {
|
||||
|
||||
@Autowired
|
||||
private TokenGranterBuilder tokenGranterBuilder;
|
||||
@Autowired
|
||||
private LogService logApi;
|
||||
@Autowired
|
||||
private ConfigValueUtil configValueUtil;
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
/**
|
||||
* 登录
|
||||
* @param parameters {grant_type}
|
||||
* @return
|
||||
* @throws LoginException
|
||||
*/
|
||||
@Override
|
||||
public ActionResult<LoginVO> login(Map<String, String> parameters) throws LoginException{
|
||||
long millis = System.currentTimeMillis();
|
||||
TokenGranter tokenGranter = tokenGranterBuilder.getGranter(parameters.getOrDefault("grant_type", ""));
|
||||
ActionResult<LoginVO> result;
|
||||
UserInfo userInfo = new UserInfo();
|
||||
try {
|
||||
String account = parameters.get("account");
|
||||
userInfo.setUserAccount(account);
|
||||
UserProvider.setLocalLoginUser(userInfo);
|
||||
result = tokenGranter.granter(parameters);
|
||||
//写入日志
|
||||
if (userInfo.getUserId() != null && !UserProvider.isTempUser(userInfo)) {
|
||||
logApi.writeLogAsync(userInfo.getUserId(), userInfo.getUserName() + "/" + userInfo.getUserAccount(), MsgCode.OA015.get(), (System.currentTimeMillis() - millis));
|
||||
}
|
||||
} catch (TenantDatabaseException tdex){
|
||||
throw tdex;
|
||||
} catch (Exception e){
|
||||
if(!(e instanceof LoginException || e instanceof TenantInvalidException)){
|
||||
String msg = e.getMessage();
|
||||
if(msg == null){
|
||||
msg = MsgCode.OA007.get();
|
||||
}
|
||||
log.error(MsgCode.OA007.get()+", Account: {}, Error: {}", parameters.getOrDefault("account", ""), e.getMessage(), e);
|
||||
throw new LoginException(msg);
|
||||
}
|
||||
String userName = StringUtil.isNotEmpty(userInfo.getUserName()) ? userInfo.getUserName()+"/"+userInfo.getUserAccount() : userInfo.getUserAccount();
|
||||
logApi.writeLogAsync(userInfo.getUserId(), userName, e.getMessage(), userInfo, 0, null, (System.currentTimeMillis()-millis));
|
||||
throw e;
|
||||
}finally{
|
||||
LoginHolder.clearUserEntity();
|
||||
TenantProvider.clearBaseSystemIfo();
|
||||
// 请求之后就删除验证码 不论结果
|
||||
String imgCode = parameters.get("timestamp");
|
||||
if(StringUtil.isNotEmpty(imgCode)) {
|
||||
redisUtil.remove(imgCode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 踢出用户, 用户将收到Websocket下线通知
|
||||
* 执行流程:认证服务退出用户->用户踢出监听->消息服务发送Websocket推送退出消息
|
||||
* @param tokens
|
||||
*/
|
||||
@Override
|
||||
public ActionResult kickoutByToken(String... tokens){
|
||||
UserProvider.kickoutByToken(tokens);
|
||||
return ActionResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 踢出用户, 用户将收到Websocket下线通知
|
||||
* 执行流程:认证服务退出用户->用户踢出监听->消息服务发送Websocket推送退出消息
|
||||
* @param userId
|
||||
* @param tenantId
|
||||
*/
|
||||
@Override
|
||||
public ActionResult kickoutByUserId(String userId, String tenantId){
|
||||
UserProvider.kickoutByUserId(userId, tenantId);
|
||||
return ActionResult.success();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
package com.yunzhupaas.service.impl;
|
||||
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.permission.entity.UserEntity;
|
||||
import com.yunzhupaas.permission.service.UserService;
|
||||
import com.yunzhupaas.service.UserDetailService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 默认使用用户名获取用户信息
|
||||
*/
|
||||
@Service(AuthConsts.USERDETAIL_ACCOUNT)
|
||||
public class UserDetailsByUserAccountServiceImpl implements UserDetailService {
|
||||
|
||||
@Autowired
|
||||
private UserService userApi;
|
||||
|
||||
@Override
|
||||
public UserEntity loadUserEntity(UserInfo userInfo) throws LoginException {
|
||||
UserEntity userEntity = userApi.getUserByAccount(userInfo.getUserAccount());
|
||||
if (userEntity == null) {
|
||||
throw new LoginException(MsgCode.LOG101.get());
|
||||
}
|
||||
return userEntity;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.yunzhupaas.service.impl;
|
||||
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.permission.entity.UserEntity;
|
||||
import com.yunzhupaas.permission.service.UserService;
|
||||
import com.yunzhupaas.service.UserDetailService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
/**
|
||||
* 使用用户ID获取用户信息
|
||||
*/
|
||||
@Service(AuthConsts.USERDETAIL_USER_ID)
|
||||
public class UserDetailsByUserIdServiceImpl implements UserDetailService {
|
||||
|
||||
private static final Integer ORDER = 1;
|
||||
|
||||
@Autowired
|
||||
private UserService userApi;
|
||||
|
||||
@Override
|
||||
public UserEntity loadUserEntity(UserInfo userInfo) throws LoginException {
|
||||
UserEntity userEntity = userApi.getInfo(userInfo.getUserId());
|
||||
if (userEntity == null) {
|
||||
throw new LoginException(MsgCode.LOG101.get());
|
||||
}
|
||||
return userEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return ORDER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.yunzhupaas.util;
|
||||
|
||||
import com.yunzhupaas.permission.entity.UserEntity;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
*/
|
||||
public class LoginHolder {
|
||||
|
||||
|
||||
private static final ThreadLocal<UserEntity> USER_CACHE = new ThreadLocal<>();
|
||||
|
||||
public static UserEntity getUserEntity(){
|
||||
return USER_CACHE.get();
|
||||
}
|
||||
|
||||
public static void setUserEntity(UserEntity userEntity){
|
||||
USER_CACHE.set(userEntity);
|
||||
}
|
||||
|
||||
public static void clearUserEntity(){
|
||||
USER_CACHE.remove();
|
||||
}
|
||||
}
|
||||
|
||||
22
yunzhupaas-oauth/yunzhupaas-oauth-controller/pom.xml
Normal file
22
yunzhupaas-oauth/yunzhupaas-oauth-controller/pom.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yunzhupaas-oauth</artifactId>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yunzhupaas-oauth-controller</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-oauth-biz</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,524 @@
|
||||
package com.yunzhupaas.controller;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.text.StrPool;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import com.yunzhupaas.base.service.SysconfigService;
|
||||
import com.yunzhupaas.config.YunzhupaasOauthConfig;
|
||||
import com.yunzhupaas.constant.MsgCode;
|
||||
import com.yunzhupaas.consts.AuthConsts;
|
||||
import com.yunzhupaas.consts.DeviceType;
|
||||
import com.yunzhupaas.consts.LoginTicketStatus;
|
||||
import com.yunzhupaas.consts.ScanCodeTicketStatus;
|
||||
import com.yunzhupaas.database.util.TenantDataSourceUtil;
|
||||
import com.yunzhupaas.granter.TokenGranter;
|
||||
import com.yunzhupaas.granter.TokenGranterBuilder;
|
||||
import com.yunzhupaas.granter.UserDetailsServiceBuilder;
|
||||
import com.yunzhupaas.model.*;
|
||||
import com.yunzhupaas.model.login.MeInfoVO;
|
||||
import com.yunzhupaas.model.login.UserSystemVO;
|
||||
import com.yunzhupaas.model.logout.LogoutResultModel;
|
||||
import com.yunzhupaas.permission.controller.SocialsUserController;
|
||||
import com.yunzhupaas.permission.model.socails.SocialsUserVo;
|
||||
import com.yunzhupaas.permission.service.UserService;
|
||||
import com.yunzhupaas.service.AuthService;
|
||||
import com.yunzhupaas.base.ActionResult;
|
||||
import com.yunzhupaas.service.LogService;
|
||||
import com.yunzhupaas.util.NoDataSourceBind;
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.config.ConfigValueUtil;
|
||||
import com.yunzhupaas.model.login.PcUserVO;
|
||||
import com.yunzhupaas.permission.entity.UserEntity;
|
||||
import com.yunzhupaas.exception.LoginException;
|
||||
import com.yunzhupaas.service.LoginService;
|
||||
import com.yunzhupaas.util.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.yunzhupaas.consts.AuthConsts.PARAMS_YUNZHUPAAS_TICKET;
|
||||
|
||||
/**
|
||||
* 登录控制器
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @version V3.1.0
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024-09-26 上午9:18
|
||||
*/
|
||||
@Tag(name = "登陆数据", description = "oauth")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/oauth")
|
||||
public class LoginController {
|
||||
|
||||
@Autowired
|
||||
private UserService userApi;
|
||||
@Autowired
|
||||
private LoginService loginService;
|
||||
@Autowired
|
||||
private AuthService authService;
|
||||
@Autowired
|
||||
private ConfigValueUtil configValueUtil;
|
||||
@Autowired
|
||||
private YunzhupaasOauthConfig oauthConfig;
|
||||
@Autowired
|
||||
private SysconfigService sysConfigApi;
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
@Autowired
|
||||
private TokenGranterBuilder tokenGranterBuilder;
|
||||
@Autowired
|
||||
private SocialsUserController socialsUserApi;
|
||||
@Autowired
|
||||
private UserDetailsServiceBuilder userDetailsServiceBuilder;
|
||||
@Autowired
|
||||
private LogService logApi;
|
||||
|
||||
/**
|
||||
* 登陆
|
||||
*
|
||||
* @param parameters 登录参数
|
||||
* @return
|
||||
* @throws LoginException 登录异常
|
||||
*/
|
||||
@NoDataSourceBind
|
||||
@Operation(summary = "登陆")
|
||||
@Parameters({
|
||||
@Parameter(name = "parameters", description = "登录参数", required = true)
|
||||
})
|
||||
@RequestMapping(value = "/Login/**", method = { RequestMethod.GET, RequestMethod.POST })
|
||||
public ActionResult<LoginVO> login(@RequestParam Map<String, String> parameters) throws LoginException {
|
||||
return authService.login(parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证密码
|
||||
*
|
||||
* @param loginForm 登录模型
|
||||
* @return
|
||||
* @throws LoginException 登录异常
|
||||
*/
|
||||
@Operation(summary = "锁屏解锁登录")
|
||||
@Parameters({
|
||||
@Parameter(name = "loginForm", description = "登录模型", required = true)
|
||||
})
|
||||
@PostMapping("/LockScreen")
|
||||
public ActionResult lockScreen(@RequestBody LoginForm loginForm) throws LoginException {
|
||||
UserEntity userEntity = userApi.getUserByAccount(loginForm.getAccount());
|
||||
if (userEntity == null) {
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
if (userInfo.getUserId() != null) {
|
||||
UserProvider.logoutByUserId(userInfo.getUserId());
|
||||
}
|
||||
throw new LoginException(MsgCode.FA001.get());
|
||||
}
|
||||
if (!Md5Util.getStringMd5(loginForm.getPassword().toLowerCase() + userEntity.getSecretkey().toLowerCase())
|
||||
.equals(userEntity.getPassword())) {
|
||||
throw new LoginException(MsgCode.OA020.get());
|
||||
}
|
||||
return ActionResult.success(MsgCode.SU005.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录注销
|
||||
*
|
||||
* @param grandtype 登录类型
|
||||
* @return
|
||||
*/
|
||||
@NoDataSourceBind
|
||||
@Operation(summary = "退出")
|
||||
@Parameters({
|
||||
@Parameter(name = "grandtype", description = "登录类型", required = true)
|
||||
})
|
||||
@RequestMapping(value = { "/Logout", "/Logout/{grandtype}" }, method = { RequestMethod.GET, RequestMethod.POST })
|
||||
public ActionResult<LogoutResultModel> logout(
|
||||
@PathVariable(value = "grandtype", required = false) String grandtype) {
|
||||
long millis = System.currentTimeMillis();
|
||||
TokenGranter tokenGranter = tokenGranterBuilder.getGranterByLogin(grandtype);
|
||||
if (tokenGranter != null) {
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
logApi.writeLogAsync(userInfo.getUserId(), userInfo.getUserName() + "/" + userInfo.getUserAccount(), "退出登录",
|
||||
userInfo, 1, 1, (System.currentTimeMillis() - millis));
|
||||
return tokenGranter.logout();
|
||||
}
|
||||
return ActionResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 踢出指定用户, 推送Websocket用户被强制下线
|
||||
*
|
||||
* @param tokens token集合
|
||||
* @param userId 租户id
|
||||
* @param tenantId 租户id
|
||||
*/
|
||||
@NoDataSourceBind
|
||||
@Operation(summary = "踢出指定用户")
|
||||
@Parameters({
|
||||
@Parameter(name = "tokens", description = "token集合"),
|
||||
@Parameter(name = "userId", description = "租户id"),
|
||||
@Parameter(name = "tenantId", description = "租户id"),
|
||||
})
|
||||
@PostMapping(value = { "/KickoutToken" })
|
||||
public void kickoutByToken(@RequestParam(value = "tokens", required = false) String[] tokens,
|
||||
@RequestParam(name = "userId", required = false) String userId,
|
||||
@RequestParam(name = "tenantId", required = false) String tenantId) {
|
||||
if (StringUtil.isNotEmpty(tokens)) {
|
||||
authService.kickoutByToken(tokens);
|
||||
} else {
|
||||
authService.kickoutByUserId(userId, tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户登录信息
|
||||
*
|
||||
* @param type Web/App
|
||||
* @return
|
||||
* @throws LoginException 登录异常
|
||||
*/
|
||||
@Operation(summary = "获取用户登录信息")
|
||||
@Parameters({
|
||||
@Parameter(name = "type", description = "Web/App")
|
||||
})
|
||||
@GetMapping("/CurrentUser")
|
||||
public ActionResult<PcUserVO> currentUser(String type, String systemCode) throws LoginException {
|
||||
if (StringUtil.isEmpty(type)) {
|
||||
type = "Web";
|
||||
} else {
|
||||
type = "App";
|
||||
}
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
if (DeviceType.TEMPUSERLIMITED.getDevice().equals(userInfo.getLoginDevice())) {
|
||||
throw new LoginException(MsgCode.OA022.get());
|
||||
}
|
||||
PcUserVO pcUserVO = loginService.getCurrentUser(type, systemCode);
|
||||
if (pcUserVO == null) {
|
||||
throw new LoginException(MsgCode.LOG001.get());
|
||||
}
|
||||
if (pcUserVO.getMenuList().isEmpty() && StringUtil.isEmpty(systemCode)) {
|
||||
List<UserSystemVO> standingList = pcUserVO.getUserInfo().getStandingList();
|
||||
for (int i = standingList.size() - 1; i >= 0; i--) {
|
||||
UserSystemVO systemVO = standingList.get(i);
|
||||
if (!systemVO.isCurrentStanding()) {
|
||||
UserEntity user = new UserEntity();
|
||||
user.setId(userInfo.getUserId());
|
||||
if ("Web".equals(type)) {
|
||||
user.setStanding(Integer.parseInt(systemVO.getId()));
|
||||
} else {
|
||||
user.setAppStanding(Integer.parseInt(systemVO.getId()));
|
||||
}
|
||||
boolean update = userApi.updateById(user);
|
||||
if (update) {
|
||||
pcUserVO = loginService.getCurrentUser(type, systemCode);
|
||||
}
|
||||
if (!pcUserVO.getMenuList().isEmpty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pcUserVO.getMenuList().isEmpty()) {
|
||||
UserProvider.logout();
|
||||
}
|
||||
return ActionResult.success(pcUserVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码信息发送
|
||||
*
|
||||
*/
|
||||
@Operation(summary = "修改密码信息发送")
|
||||
@PostMapping("/updatePasswordMessage")
|
||||
public ActionResult updatePasswordMessage() {
|
||||
loginService.updatePasswordMessage();
|
||||
return ActionResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 图形验证码
|
||||
*
|
||||
* @param codeLength 验证码长度
|
||||
* @param timestamp 验证码标识
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "图形验证码")
|
||||
@Parameters({
|
||||
@Parameter(name = "codeLength", description = "验证码长度", required = true),
|
||||
@Parameter(name = "timestamp", description = "验证码标识", required = true)
|
||||
})
|
||||
@GetMapping("/ImageCode/{codeLength}/{timestamp}")
|
||||
public void imageCode(@PathVariable("codeLength") Integer codeLength, @PathVariable("timestamp") String timestamp) {
|
||||
DownUtil.downCode(codeLength);
|
||||
redisUtil.insert(timestamp, ServletUtil.getSession().getAttribute(CodeUtil.RANDOMCODEKEY), 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销用户
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "注销用户")
|
||||
@PostMapping("/logoutCurrentUser")
|
||||
public ActionResult logoutCurrentUser() {
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
if (userInfo.getIsAdministrator() != null && UserProvider.getUser().getIsAdministrator()) {
|
||||
return ActionResult.fail(MsgCode.OA023.get());
|
||||
}
|
||||
if (userInfo.getIsAdministrator() != null) {
|
||||
if (!userInfo.getIsAdministrator()) {
|
||||
userApi.delete(userApi.getInfo(userInfo.getUserId()));
|
||||
UserProvider.kickoutByUserId(userInfo.getUserId(), userInfo.getTenantId());
|
||||
}
|
||||
}
|
||||
return ActionResult.success(MsgCode.SU005.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否需要验证码
|
||||
*
|
||||
* @param account 账号
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "判断是否需要验证码")
|
||||
@Parameters({
|
||||
@Parameter(name = "account", description = "账号", required = true)
|
||||
})
|
||||
@GetMapping("/getConfig/{account}")
|
||||
public ActionResult<LoginModel> check(@PathVariable("account") String account) throws LoginException {
|
||||
LoginModel loginModel = new LoginModel();
|
||||
if (configValueUtil.isMultiTenancy()) {
|
||||
LoginForm loginForm = new LoginForm();
|
||||
loginForm.setAccount(account);
|
||||
UserInfo userInfo = new UserInfo();
|
||||
userInfo.setUserAccount(loginForm.getAccount());
|
||||
userInfo = loginService.getTenantAccount(userInfo);
|
||||
}
|
||||
// 获取配置
|
||||
BaseSystemInfo sysConfigInfo = sysConfigApi.getSysInfo();
|
||||
// 是否开启验证码
|
||||
if (Objects.nonNull(sysConfigInfo) && "1".equals(String.valueOf(sysConfigInfo.getEnableVerificationCode()))) {
|
||||
loginModel.setEnableVerificationCode(1);
|
||||
Integer verificationCodeNumber = sysConfigInfo.getVerificationCodeNumber();
|
||||
loginModel.setVerificationCodeNumber(verificationCodeNumber == null ? 4 : verificationCodeNumber);
|
||||
return ActionResult.success(loginModel);
|
||||
}
|
||||
loginModel.setEnableVerificationCode(0);
|
||||
return ActionResult.success(loginModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录配置, 是否需要跳转、第三方登录信息
|
||||
*
|
||||
* @return {re}
|
||||
* @throws LoginException 登录异常
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "获取登录配置")
|
||||
@GetMapping("/getLoginConfig")
|
||||
public ActionResult<LoginConfigModel> getLoginConfig() {
|
||||
LoginConfigModel loginConfigModel = new LoginConfigModel();
|
||||
if (oauthConfig.getSsoEnabled()) {
|
||||
String url = oauthConfig.getLoginPath() + StrPool.SLASH + oauthConfig.getDefaultSSO();
|
||||
loginConfigModel.setRedirect(true);
|
||||
loginConfigModel.setUrl(url);
|
||||
loginConfigModel.setTicketParams(PARAMS_YUNZHUPAAS_TICKET);
|
||||
} else {
|
||||
// 追加第三方登录配置
|
||||
List<SocialsUserVo> loginList = socialsUserApi.getLoginList(PARAMS_YUNZHUPAAS_TICKET.toUpperCase());
|
||||
if (CollectionUtil.isNotEmpty(loginList)) {
|
||||
loginConfigModel.setSocialsList(loginList);
|
||||
loginConfigModel.setRedirect(false);
|
||||
loginConfigModel.setTicketParams(PARAMS_YUNZHUPAAS_TICKET);
|
||||
}
|
||||
}
|
||||
return ActionResult.success(loginConfigModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录票据
|
||||
*
|
||||
* @return {msg:有效期, data:票据}
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "获取登录票据")
|
||||
@GetMapping("/getTicket")
|
||||
public ActionResult<String> getTicket() {
|
||||
LoginTicketModel ticketModel = new LoginTicketModel();
|
||||
ticketModel.setTicketTimeout(System.currentTimeMillis() + oauthConfig.getTicketTimeout() * 1000);
|
||||
String ticket = TicketUtil.createTicket(ticketModel, oauthConfig.getTicketTimeout());
|
||||
return ActionResult.success(ticketModel.getTicketTimeout().toString(), ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测票据登录状态
|
||||
*
|
||||
* @return {re}
|
||||
* @throws LoginException
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "获取登录状态")
|
||||
@GetMapping("/getTicketStatus/{ticket}")
|
||||
public ActionResult<LoginTicketModel> getTicketStatus(@PathVariable("ticket") String ticket) {
|
||||
LoginTicketModel ticketModel = TicketUtil.parseTicket(ticket);
|
||||
if (ticketModel == null) {
|
||||
ticketModel = new LoginTicketModel().setStatus(LoginTicketStatus.Invalid.getStatus()).setValue("票据失效!");
|
||||
} else {
|
||||
if (ticketModel.getStatus() != LoginTicketStatus.UnLogin.getStatus()
|
||||
&& ticketModel.getStatus() != LoginTicketStatus.UnBind.getStatus()) {
|
||||
TicketUtil.deleteTicket(ticket);
|
||||
}
|
||||
}
|
||||
return ActionResult.success(ticketModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 官网重置密码专用
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "官网重置密码专用")
|
||||
@GetMapping("/resetOfficialPassword/{mobile}/{code}")
|
||||
public ActionResult resetOfficialPassword(@PathVariable("mobile") String mobile, @PathVariable("code") String code)
|
||||
throws LoginException {
|
||||
// 校验验证码
|
||||
TenantDataSourceUtil.checkOfficialSmsCode(mobile, code, 2);
|
||||
// 切换租户
|
||||
LoginForm loginForm = new LoginForm();
|
||||
loginForm.setAccount(mobile);
|
||||
UserInfo userInfo = new UserInfo();
|
||||
userInfo.setUserAccount(loginForm.getAccount());
|
||||
try {
|
||||
userInfo = loginService.getTenantAccount(userInfo);
|
||||
} catch (Exception e) {
|
||||
return ActionResult.fail(MsgCode.LOG105.get());
|
||||
}
|
||||
|
||||
// 重置密码 123456
|
||||
UserEntity userEntity = userDetailsServiceBuilder.getUserDetailService(AuthConsts.USERDETAIL_ACCOUNT)
|
||||
.loadUserEntity(userInfo);
|
||||
userEntity.setPassword("e10adc3949ba59abbe56e057f20f883e");
|
||||
userEntity.setPassword(
|
||||
Md5Util.getStringMd5(userEntity.getPassword().toLowerCase() + userEntity.getSecretkey().toLowerCase()));
|
||||
boolean result = userApi.updateById(userEntity);
|
||||
if (result) {
|
||||
return ActionResult.success(MsgCode.LOG205.get());
|
||||
} else {
|
||||
return ActionResult.fail(MsgCode.LOG206.get());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成扫码凭证
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "生成扫码凭证")
|
||||
@GetMapping("/codeCertificate")
|
||||
public ActionResult codeCertificate() throws LoginException {
|
||||
ScanCodeLoginConfigModel ticketModel = new ScanCodeLoginConfigModel();
|
||||
ticketModel.setTicketTimeout(System.currentTimeMillis() + configValueUtil.getCodeCertificateTimeout() * 1000);
|
||||
String ticket = TicketUtil.createTicket(ticketModel, configValueUtil.getCodeCertificateTimeout());
|
||||
return ActionResult.success(ticketModel.getTicketTimeout().toString(), ticket);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扫码凭证状态
|
||||
*
|
||||
* @param ticket
|
||||
* @return
|
||||
* @throws LoginException
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "获取扫码凭证状态")
|
||||
@GetMapping("/codeCertificateStatus/{ticket}")
|
||||
public ActionResult codeCertificateStatus(@PathVariable("ticket") String ticket) throws LoginException {
|
||||
ScanCodeLoginConfigModel ticketModel = TicketUtil.parseTicket(ticket);
|
||||
if (ticketModel == null) {
|
||||
ticketModel = new ScanCodeLoginConfigModel();
|
||||
ticketModel.setStatus(ScanCodeTicketStatus.Invalid.getStatus());
|
||||
}
|
||||
return ActionResult.success(ticketModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认登录
|
||||
*
|
||||
* @param ticket
|
||||
* @return
|
||||
* @throws LoginException
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "确认登录")
|
||||
@GetMapping("/confirmLogin/{ticket}")
|
||||
public ActionResult confirmLogin(@PathVariable("ticket") String ticket) throws LoginException {
|
||||
ScanCodeLoginConfigModel ticketModel = TicketUtil.parseTicket(ticket);
|
||||
if (ticketModel == null || !Objects.equals(ticketModel.getStatus(), 1)) {
|
||||
ticketModel = new ScanCodeLoginConfigModel();
|
||||
ticketModel.setStatus(ScanCodeTicketStatus.Invalid.getStatus());
|
||||
return ActionResult.success(ticketModel);
|
||||
}
|
||||
ticketModel.setStatus(ScanCodeTicketStatus.Success.getStatus());
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put("grant_type", "scancode");
|
||||
parameters.put("token", UserProvider.getToken());
|
||||
ticketModel.setValue(authService.login(parameters).getData().getToken());
|
||||
TicketUtil.updateTicket(ticket, ticketModel, null);
|
||||
return ActionResult.success(ticketModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改扫码凭证状态
|
||||
*
|
||||
* @param ticket
|
||||
* @return
|
||||
* @throws LoginException
|
||||
*/
|
||||
@NoDataSourceBind()
|
||||
@Operation(summary = "更改扫码凭证状态")
|
||||
@GetMapping("/setCodeCertificateStatus/{ticket}/{status}")
|
||||
public ActionResult setCodeCertificateStatus(@PathVariable("ticket") String ticket,
|
||||
@PathVariable("status") Integer status) throws LoginException {
|
||||
ScanCodeLoginConfigModel ticketModel = TicketUtil.parseTicket(ticket);
|
||||
if (ticketModel == null) {
|
||||
ticketModel = new ScanCodeLoginConfigModel();
|
||||
ticketModel.setStatus(ScanCodeTicketStatus.Invalid.getStatus());
|
||||
} else {
|
||||
ticketModel.setStatus(status);
|
||||
}
|
||||
ticketModel.setTicketTimeout(System.currentTimeMillis() + configValueUtil.getCodeCertificateTimeout() * 1000);
|
||||
TicketUtil.updateTicket(ticket, ticketModel, configValueUtil.getCodeCertificateTimeout());
|
||||
return ActionResult.success(ticketModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户登录信息
|
||||
*
|
||||
* @return
|
||||
* @throws LoginException 登录异常
|
||||
*/
|
||||
@Operation(summary = "获取用户基本信息")
|
||||
@GetMapping("/me")
|
||||
public ActionResult<MeInfoVO> me() throws LoginException {
|
||||
UserInfo userInfo = UserProvider.getUser();
|
||||
MeInfoVO meInfoVO = new MeInfoVO()
|
||||
.setUserName(userInfo.getUserName())
|
||||
.setUserId(userInfo.getUserId())
|
||||
.setUserAccount(userInfo.getUserAccount())
|
||||
.setTenantId(userInfo.getTenantId());
|
||||
return ActionResult.success(meInfoVO);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(Md5Util.getStringMd5("123456" + "26916bdf390242c9b0ac7ec1442a329e".toLowerCase()));
|
||||
}
|
||||
}
|
||||
32
yunzhupaas-oauth/yunzhupaas-oauth-entity/pom.xml
Normal file
32
yunzhupaas-oauth/yunzhupaas-oauth-entity/pom.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>yunzhupaas-oauth</artifactId>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<version>5.2.0-RELEASE</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yunzhupaas-oauth-entity</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-common-all</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-system-entity</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yunzhupaas</groupId>
|
||||
<artifactId>yunzhupaas-permission-entity</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.yunzhupaas;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.yunzhupaas.base.entity.SuperExtendEntity;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
*
|
||||
* baseTenant
|
||||
* @版本: V3.1.0
|
||||
* @版权: 深圳市乐程软件有限公司(http://www.szlecheng.cn)
|
||||
* @作者: 云筑产品开发平台组
|
||||
* @日期: 2020-12-17 16:09:07
|
||||
*/
|
||||
@Data
|
||||
@TableName("base_tenant")
|
||||
public class TenantEntity extends SuperExtendEntity.SuperExtendDEEntity<String> {
|
||||
|
||||
@TableField("f_en_code")
|
||||
private String enCode;
|
||||
|
||||
@TableField("f_full_name")
|
||||
private String fullName;
|
||||
|
||||
@TableField("f_company_name")
|
||||
private String comPanyName;
|
||||
|
||||
@TableField("f_expires_time")
|
||||
private Date expiresTime;
|
||||
|
||||
@TableField("f_db_name")
|
||||
private String dbName;
|
||||
|
||||
@TableField("f_ip_address")
|
||||
private String ipAddress;
|
||||
|
||||
@TableField("f_ip_address_name")
|
||||
private String ipAddressName;
|
||||
|
||||
@TableField("f_source_website")
|
||||
private String sourceWebsite;
|
||||
|
||||
/**
|
||||
* 数据模式
|
||||
*/
|
||||
@TableField("f_data_schema")
|
||||
private Integer dataSchema;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.yunzhupaas.entity;
|
||||
|
||||
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 lombok.Data;
|
||||
|
||||
/**
|
||||
* 租户日志
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @version v5.2.7
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2023/09/27
|
||||
*/
|
||||
@Data
|
||||
@TableName("base_tenantlog")
|
||||
public class TenantlogEntity {
|
||||
|
||||
/**
|
||||
* 自然主键
|
||||
*/
|
||||
@TableId("F_ID")
|
||||
@JSONField(name = "F_Id")
|
||||
private String fId;
|
||||
|
||||
/**
|
||||
* 租户主键
|
||||
*/
|
||||
@TableField("F_TENANTID")
|
||||
@JSONField(name = "F_TenantId")
|
||||
private String fTenantid;
|
||||
|
||||
/**
|
||||
* 登录账户
|
||||
*/
|
||||
@TableField("F_LOGINACCOUNT")
|
||||
@JSONField(name = "F_LoginAccount")
|
||||
private String fLoginaccount;
|
||||
|
||||
/**
|
||||
* IP地址
|
||||
*/
|
||||
@TableField("F_LOGINIPADDRESS")
|
||||
@JSONField(name = "F_LoginIPAddress")
|
||||
private String fLoginipaddress;
|
||||
|
||||
/**
|
||||
* IP所在城市
|
||||
*/
|
||||
@TableField("F_LOGINIPADDRESSNAME")
|
||||
@JSONField(name = "F_LoginIPAddressName")
|
||||
private String fLoginipaddressname;
|
||||
|
||||
/**
|
||||
* 来源网站
|
||||
*/
|
||||
@TableField("F_LOGINSOURCEWEBSITE")
|
||||
@JSONField(name = "F_LoginSourceWebsite")
|
||||
private String fLoginsourcewebsite;
|
||||
/**
|
||||
* 登录时间
|
||||
*/
|
||||
@TableField("F_LOGINTIME")
|
||||
@JSONField(name = "F_LoginTime")
|
||||
private String fLogintime;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
@TableField("F_DESCRIPTION")
|
||||
@JSONField(name = "F_Description")
|
||||
private String fDescription;
|
||||
|
||||
/**
|
||||
* 租户id
|
||||
*/
|
||||
@TableField("F_TENANTID")
|
||||
private String tenantId;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.yunzhupaas.model;
|
||||
|
||||
import com.yunzhupaas.base.UserInfo;
|
||||
import com.yunzhupaas.base.entity.SystemEntity;
|
||||
import com.yunzhupaas.permission.entity.UserEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BuildUserCommonInfoModel implements Serializable {
|
||||
|
||||
private UserInfo userInfo;
|
||||
private SystemEntity mainSystemEntity;
|
||||
private SystemEntity workSystemEntity;
|
||||
private UserEntity userEntity;
|
||||
private BaseSystemInfo baseSystemInfo;
|
||||
private String systemId;
|
||||
private String type;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.yunzhupaas.model;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 通用登录配置
|
||||
* 是否跳转
|
||||
* 第三方登录配置
|
||||
* @author 云筑产品开发平台组
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
*/
|
||||
@Data
|
||||
public class LoginConfigModel<T> {
|
||||
|
||||
/**
|
||||
* 是否跳转
|
||||
*/
|
||||
@Schema(description = "是否跳转")
|
||||
private boolean redirect = false;
|
||||
|
||||
/**
|
||||
* 跳转URL地址
|
||||
*/
|
||||
@Schema(description = "跳转URL地址")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 跳转登录轮询票据参数名称
|
||||
*/
|
||||
@Schema(description = "跳转登录轮询票据")
|
||||
private String ticketParams;
|
||||
|
||||
|
||||
/**
|
||||
* 第三方登录列表
|
||||
*/
|
||||
@Schema(description = "第三方登录列表")
|
||||
List<T> socialsList;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.yunzhupaas.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 登陆判断是否需要验证码
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @version V3.1.0
|
||||
* @copyright 深圳市乐程软件有限公司(http://www.szlecheng.cn)
|
||||
* @date 2024-12-31
|
||||
*/
|
||||
@Data
|
||||
public class LoginModel implements Serializable {
|
||||
|
||||
/**
|
||||
* 是否开启验证码
|
||||
*/
|
||||
private Integer enableVerificationCode;
|
||||
|
||||
/**
|
||||
* 验证码位数
|
||||
*/
|
||||
private Integer verificationCodeNumber;
|
||||
|
||||
public Integer getEnableVerificationCode() {
|
||||
return enableVerificationCode;
|
||||
}
|
||||
|
||||
public void setEnableVerificationCode(Integer enableVerificationCode) {
|
||||
this.enableVerificationCode = enableVerificationCode;
|
||||
}
|
||||
|
||||
public Integer getVerificationCodeNumber() {
|
||||
return verificationCodeNumber;
|
||||
}
|
||||
|
||||
public void setVerificationCodeNumber(Integer verificationCodeNumber) {
|
||||
this.verificationCodeNumber = verificationCodeNumber;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.yunzhupaas.model;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
//@Builder
|
||||
public class LoginVO {
|
||||
@Schema(description = "token")
|
||||
private String token;
|
||||
@Schema(description = "主题")
|
||||
private String theme;
|
||||
|
||||
/**
|
||||
* 卫翎信息 官网专用
|
||||
*/
|
||||
private Map<String, String> wl_qrcode;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.yunzhupaas.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 第三方未绑定模型
|
||||
*
|
||||
* @author 云筑产品开发平台组
|
||||
* @version V3.4.2
|
||||
* @copyright 深圳市乐程软件有限公司
|
||||
* @date 2024/9/19 15:06:31
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class SocialUnbindModel {
|
||||
String socialType;
|
||||
String socialUnionid;
|
||||
String socialName;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.yunzhupaas.model;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import com.yunzhupaas.base.Pagination;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class UserLogForm extends Pagination implements Serializable {
|
||||
@Schema(description = "开始时间")
|
||||
private String startTime;
|
||||
@Schema(description = "结束时间")
|
||||
private String endTime;
|
||||
@Schema(description = "分类")
|
||||
private int category;
|
||||
@Schema(description = "是否登录成功标志")
|
||||
private Integer loginMark;
|
||||
@Schema(description = "登录类型")
|
||||
private Integer loginType;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user