feat(core): 平台添加用户名登录方式 支持钉钉授权

平台添加用户名登录方式 支持钉钉授权
yun-zuoyi
wynne1005 4 years ago
parent c65a1d735c
commit 762458a1d5

@ -92,6 +92,31 @@ public interface ISystemLoginService {
SessionUser queryCheckE9SaAdminLogin(SaAdminToken saAdminToken);
/**
* Name
*
* @param userToken token
* @return
*/
@ApiOperation(value = "封装用户", notes = "封装普通用户信息")
SessionUser queryCheckNameUserLogin(UserToken userToken);
/**
* NameAdmin
*
* @param adminToken admin token
* @return
*/
@ApiOperation(value = "封装用户", notes = "封装管理员信息")
SessionUser queryCheckNameAdminLogin(AdminToken adminToken);
/**
* Name SA
* @param saAdminToken sa token
* @return
*/
@ApiOperation(value = "封装用户", notes = "封装超级管理员信息")
SessionUser queryCheckNameSaAdminLogin(SaAdminToken saAdminToken);
/**
*
*
* @param loginName

@ -89,6 +89,11 @@
<dependency>
<groupId>i3plus.sdk</groupId>
<artifactId>i3plus-sdk-dingtalk</artifactId>
</dependency>
<dependency>
<groupId>i3plus.sdk</groupId>
<artifactId>i3plus-sdk-sms</artifactId>
</dependency>
@ -174,6 +179,7 @@
<groupId>i3plus.pojo</groupId>
<artifactId>i3plus-pojo-mes</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>

@ -7,6 +7,9 @@ import cn.estsh.i3plus.core.apiservice.auth.realm.UserAuthRealm;
import cn.estsh.i3plus.core.apiservice.auth.realm.strategy.e9.E9AdminAuthRealm;
import cn.estsh.i3plus.core.apiservice.auth.realm.strategy.e9.E9SaAuthRealm;
import cn.estsh.i3plus.core.apiservice.auth.realm.strategy.e9.E9UserAuthRealm;
import cn.estsh.i3plus.core.apiservice.auth.realm.strategy.name.NameAdminAuthRealm;
import cn.estsh.i3plus.core.apiservice.auth.realm.strategy.name.NameSaAuthRealm;
import cn.estsh.i3plus.core.apiservice.auth.realm.strategy.name.NameUserAuthRealm;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ImppEnumUtil;
@ -107,6 +110,21 @@ public class ShiroAuthConfiguration {
return new E9UserAuthRealm();
}
@Bean
public NameAdminAuthRealm nameAdminAuthRealm() {
return new NameAdminAuthRealm();
}
@Bean
public NameSaAuthRealm nameSaAuthRealm() {
return new NameSaAuthRealm();
}
@Bean
public NameUserAuthRealm nameUserAuthRealm() {
return new NameUserAuthRealm();
}
public Map<String, RoleRealmModel> supportRealmMap() {
//支持的授权规则
Map<String, RoleRealmModel> realms = new HashMap(8);
@ -123,6 +141,12 @@ public class ShiroAuthConfiguration {
.saRealm(e9SaAuthRealm()).build();
realms.put(ImppEnumUtil.AUTH_LOGIN_STRATEGY.E9.getCode(), e9RoleRealmModel);
RoleRealmModel nameRoleRealmModel = RoleRealmModel.builder()
.userRealm(nameUserAuthRealm())
.adminRealm(nameAdminAuthRealm())
.saRealm(nameSaAuthRealm()).build();
realms.put(ImppEnumUtil.AUTH_LOGIN_STRATEGY.NAME.getCode(), nameRoleRealmModel);
return realms;
}

@ -0,0 +1,55 @@
package cn.estsh.i3plus.core.apiservice.auth.realm.strategy.name;
import cn.estsh.i3plus.core.api.iservice.base.ISystemLoginService;
import cn.estsh.i3plus.pojo.base.shirotoken.AdminToken;
import cn.estsh.i3plus.pojo.platform.bean.SessionUser;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Description :
* @Reference :
* @Author : alwaysfrin
* @CreateDate : 2018-10-13 14:04
* @Modify:
**/
public class NameAdminAuthRealm extends AuthorizingRealm {
public static final Logger LOGGER = LoggerFactory.getLogger(NameAdminAuthRealm.class);
@Autowired
private ISystemLoginService systemLoginService;
public NameAdminAuthRealm() {
//添加支持的token
this.setAuthenticationTokenClass(AdminToken.class);
}
//权限验证
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return new SimpleAuthorizationInfo();
}
//令牌确认
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
try {
//管理员令牌
SessionUser sessionUser = systemLoginService.queryCheckNameAdminLogin((AdminToken) authenticationToken);
LOGGER.info("管理员令牌验证:{}", sessionUser);
return new SimpleAuthenticationInfo(sessionUser, ((AdminToken) authenticationToken).getLoginName(), this.getName());
} catch (Exception e) {
e.printStackTrace();
throw new AuthenticationException(e.getMessage());
}
}
}

@ -0,0 +1,50 @@
package cn.estsh.i3plus.core.apiservice.auth.realm.strategy.name;
import cn.estsh.i3plus.core.api.iservice.base.ISystemLoginService;
import cn.estsh.i3plus.pojo.base.shirotoken.SaAdminToken;
import cn.estsh.i3plus.pojo.platform.bean.SessionUser;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Description :
* @Reference :
* @Author : alwaysfrin
* @CreateDate : 2018-10-13 14:04
* @Modify:
**/
public class NameSaAuthRealm extends AuthorizingRealm {
public static final Logger LOGGER = LoggerFactory.getLogger(NameSaAuthRealm.class);
@Autowired
private ISystemLoginService systemLoginService;
public NameSaAuthRealm() {
//添加支持的token
this.setAuthenticationTokenClass(SaAdminToken.class);
}
//权限验证
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return new SimpleAuthorizationInfo();
}
//令牌确认
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//管理员令牌
SessionUser sessionUser = systemLoginService.queryCheckNameSaAdminLogin((SaAdminToken) authenticationToken);
LOGGER.info("超级管理员令牌验证:{}", sessionUser);
return new SimpleAuthenticationInfo(sessionUser, ((SaAdminToken) authenticationToken).getLoginName(), this.getName());
}
}

@ -0,0 +1,55 @@
package cn.estsh.i3plus.core.apiservice.auth.realm.strategy.name;
import cn.estsh.i3plus.core.api.iservice.base.ISystemLoginService;
import cn.estsh.i3plus.pojo.base.shirotoken.UserToken;
import cn.estsh.i3plus.pojo.platform.bean.SessionUser;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Description :
* @Reference :-
* @Author : alwaysfrin
* @CreateDate : 2018-10-13 14:04
* @Modify:
**/
public class NameUserAuthRealm extends AuthorizingRealm {
public static final Logger LOGGER = LoggerFactory.getLogger(NameUserAuthRealm.class);
@Autowired
private ISystemLoginService systemLoginService;
public NameUserAuthRealm() {
//添加支持的token
this.setAuthenticationTokenClass(UserToken.class);
}
//权限验证
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return new SimpleAuthorizationInfo();
}
//令牌确认
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
try {
//管理员令牌
SessionUser sessionUser = systemLoginService.queryCheckNameUserLogin((UserToken) authenticationToken);
LOGGER.info("用户令牌验证:{}", sessionUser);
return new SimpleAuthenticationInfo(sessionUser, ((UserToken) authenticationToken).getLoginName(), this.getName());
} catch (Exception e) {
e.printStackTrace();
throw new AuthenticationException(e.getMessage());
}
}
}

@ -28,6 +28,7 @@ import cn.estsh.i3plus.pojo.model.platform.SysLoginModel;
import cn.estsh.i3plus.pojo.model.platform.UserDetailModel;
import cn.estsh.i3plus.pojo.model.platform.UserDetailPagerModel;
import cn.estsh.i3plus.pojo.platform.bean.*;
import cn.estsh.i3plus.sdk.dingtalk.cn.estsh.i3plus.sdk.service.IDingTalkService;
import cn.estsh.impp.framework.base.controller.CoreBaseController;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
@ -41,6 +42,8 @@ import cn.estsh.impp.framework.boot.util.ResultBean;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import cn.estsh.impp.framework.boot.util.ValidatorBean;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.response.OapiUserGetResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.swagger.annotations.Api;
@ -152,6 +155,9 @@ public class WhiteController extends CoreBaseController {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private IDingTalkService dingTalkService;
private Cache<String, Integer> unsavedLocaleResSwitch = CacheBuilder.newBuilder()
.maximumSize(1)
.expireAfterWrite(1, TimeUnit.MINUTES)
@ -293,6 +299,54 @@ public class WhiteController extends CoreBaseController {
return Optional.ofNullable(data);
}
@GetMapping(value = "/auth/dingtalk/login")
@ApiOperation(value = "登录", notes = "登录")
public ResultBean loginByPhoneNumber(HttpServletRequest request, String dingTalkTmpAuthCode,
@RequestParam(required = false) String languageCode,
@RequestParam(required = false) String deviceId) {
SysLoginModel loginModel = SysLoginModel.builder()
.dingTalkTmpAuthCode(dingTalkTmpAuthCode)
.languageCode(languageCode)
.deviceId(deviceId)
.loginStrategy(ImppEnumUtil.AUTH_LOGIN_STRATEGY.NAME.getCode()).build();
String dingTalkUrl = RedisCacheTool.getSysConfigStrVal(PlatformConstWords.DINGTALK_URL);
String dingTalkAppKey = RedisCacheTool.getSysConfigStrVal(PlatformConstWords.DINGTALK_APP_KEY);
String dingTalkAppSecret = RedisCacheTool.getSysConfigStrVal(PlatformConstWords.DINGTALK_APP_SECRET);
String dingTalkWhiteList = RedisCacheTool.getSysConfigStrVal(PlatformConstWords.DINGTALK_WHITE_LIST);
if (StringUtils.isEmpty(dingTalkUrl) ||
StringUtils.isEmpty(dingTalkAppKey) ||
StringUtils.isEmpty(dingTalkAppSecret) ||
StringUtils.isEmpty(dingTalkWhiteList)) {
return ResultBean.fail("访问钉钉的系统参数缺失,请在平台的系统参数中进行配置");
}
Optional<OapiV2UserGetResponse> userInfo =
dingTalkService.getUserInfo(dingTalkUrl, dingTalkAppKey, dingTalkAppSecret, loginModel.getDingTalkTmpAuthCode());
if (userInfo.isPresent()) {
String mobile = userInfo.get().getResult().getMobile();
if (StringUtils.isEmpty(mobile)) {
return ResultBean.fail("用户并未在钉钉中设置手机号 或 钉钉接口权限不足无法获取到手机号");
}
if (!Arrays.asList(dingTalkWhiteList.split(",")).contains(mobile)) {
return ResultBean.fail("对指定手机号允许,权限不足,请联系管理员");
}
SysUser sysUserByPhone = userService.getSysUserByPhone(mobile);
if (sysUserByPhone == null) {
return ResultBean.fail("未根据用户手机在平台中找到相应记录 钉钉获取的手机号为" + mobile);
}
loginModel.setLoginName(sysUserByPhone.getUserLoginName());
loginModel.setPhoneNumber(mobile);
} else {
return ResultBean.fail("获取钉钉用户信息失败");
}
String beanName = ImppEnumUtil.AUTH_LOGIN_STRATEGY.codeOfStrategyName(loginModel.getLoginStrategy());
ISystemLoginStrategyService loginStrategyService = (ISystemLoginStrategyService) SpringContextsUtil.getBean(beanName);
return loginByStrategy(request, loginModel, loginStrategyService.login());
}
@GetMapping(value = "/auth/login")
@ApiOperation(value = "登录", notes = "登录")
public ResultBean login(HttpServletRequest request, String loginName, String loginPwd,

@ -73,7 +73,7 @@ public class SystemLoginService implements ISystemLoginService {
}
public static void main(String[] args) {
System.out.println(1+2+"a");
System.out.println(1 + 2 + "a");
}
@Override
@ -138,6 +138,29 @@ public class SystemLoginService implements ISystemLoginService {
}
@Override
public SessionUser queryCheckNameUserLogin(UserToken userToken) {
//验证用户
SysUser user = getUserLoginInfo(userToken.getLoginName());
LOGGER.info("【验证用户checkUserLogin】{}", user);
//用户单地登录
return packSessionUser(user, CommonEnumUtil.USER_TYPE.USER.getCode(), userToken.getLanguageCode());
}
@Override
public SessionUser queryCheckNameAdminLogin(AdminToken adminToken) {
//验证用户
SysUser user = getUserLoginInfo(adminToken.getLoginName());
//未抛异常,封装用户
return packSessionUser(user, CommonEnumUtil.USER_TYPE.ADMIN.getCode(), adminToken.getLanguageCode());
}
@Override
public SessionUser queryCheckNameSaAdminLogin(SaAdminToken saAdminToken) {
SysUser user = getUserLoginInfo(saAdminToken.getLoginName());
return packSessionUser(user, CommonEnumUtil.USER_TYPE.SA.getCode(), saAdminToken.getLanguageCode());
}
@Override
@ApiOperation(value = "登录密码错误", notes = "登录密码错误记录错误次数功能")
public Integer doLoginPasswordError(String loginName, String sessionId) {
SysUser user = sysUserRDao.getByProperty(new String[]{"userLoginName", "isValid"},

@ -0,0 +1,92 @@
package cn.estsh.i3plus.core.apiservice.serviceimpl.base.login.strategy;
import cn.estsh.i3plus.core.api.iservice.base.ISystemLoginService;
import cn.estsh.i3plus.core.api.iservice.base.ISystemLoginStrategyService;
import cn.estsh.i3plus.core.api.iservice.busi.ILicenseClickService;
import cn.estsh.i3plus.core.api.iservice.busi.ISysUserService;
import cn.estsh.i3plus.platform.common.tool.ServletRequestTool;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.platform.common.util.PlatformConstWords;
import cn.estsh.i3plus.pojo.base.bean.BaseThreadLocal;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ImppEnumUtil;
import cn.estsh.i3plus.pojo.model.platform.SysLoginModel;
import cn.estsh.i3plus.pojo.platform.bean.SessionUser;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import cn.estsh.impp.framework.boot.util.RedisCacheTool;
import cn.estsh.impp.framework.boot.util.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.function.BiFunction;
import static cn.estsh.i3plus.platform.common.util.CommonConstWords.DEFAULT_LANGUAGE;
/**
* @author Wynne.Lu
* @date 2021/1/18 10:53
* @desc
*/
@Lazy
@Slf4j
@Service
public class NameLoginStrategy implements ISystemLoginStrategyService {
@Resource(name = "redisCore")
protected ImppRedis redisCore;
@Autowired
private ILicenseClickService licenseClickService;
@Autowired
private ISysUserService userService;
@Autowired
private ISystemLoginService loginService;
@Override
public BiFunction<HttpServletRequest, SysLoginModel, ResultBean> login() {
return (request, loginModel) -> {
licenseClickService.checkLicenseNumberLogin();
// TODO 后期移除,暂时用于避免自动登录后前台没有正确的传输组织代码信息
if ("null".equals(loginModel.getLanguageCode())|| StringUtils.isEmpty(loginModel.getLanguageCode())) {
loginModel.setLanguageCode(DEFAULT_LANGUAGE);
}
// 设置语言代码
BaseThreadLocal.setData(BaseThreadLocal.LANGUAGE_CODE, loginModel.getLanguageCode());
BaseThreadLocal.setData(PlatformConstWords.AUTH_LOGIN_STRATEGY, ImppEnumUtil.AUTH_LOGIN_STRATEGY.NAME.getCode());
int sessionMode = RedisCacheTool.getSysConfigIntVal(CommonConstWords.CONFIG_SESSION_MODE, CommonConstWords.CONFIG_SESSION_MODE_DEFAULT);
if (sessionMode != CommonEnumUtil.SESSION_MODE.SEIZE.getValue()) {
AuthUtil.logout();
}
SessionUser user = userService.loginUser(
loginModel.getLoginName().trim(),
loginModel.getLoginName().trim(),
loginModel.getLanguageCode(),
loginService.getLoginPlatform(request).getValue(),
loginModel.getDeviceId()
);
String redisKey = CommonConstWords.USER_LOGIN_ERROR + "_" + user.getUser().getId();
redisCore.deleteKey(redisKey);
ResultBean result = new ResultBean(true, AuthUtil.getSession().getId().toString(), AuthUtil.getSessionUser());
result.setUrl("/");
AuthUtil.setOrganize(user.getUser().getOrganize());
return result;
};
}
}

@ -1,5 +1,5 @@
#\u4F7F\u7528\u914D\u7F6E
spring.profiles.active=dev
spring.profiles.active=test
#\u9879\u76EE\u63CF\u8FF0\u4FE1\u606F\uFF08swagger\u4E2D\u663E\u5F0F\uFF09\uFF0C\u4E2D\u6587\u4F7F\u7528uncode\u8F6C\u7801
desc.application.name=\u6838\u5FC3\u7BA1\u7406\u540E\u53F0

@ -129,6 +129,12 @@
<dependency>
<groupId>i3plus.sdk</groupId>
<artifactId>i3plus-sdk-dingtalk</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>i3plus.sdk</groupId>
<artifactId>i3plus-sdk-wechat</artifactId>
<version>${project.version}</version>
</dependency>
@ -189,7 +195,7 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
<version>5.1.49</version>
</dependency>
<!-- oracle -->

Loading…
Cancel
Save