集成钉钉登录
This commit is contained in:
parent
8ca13edc9b
commit
9b31643e83
|
@ -1,26 +1,47 @@
|
|||
package com.snow.web.controller.dingtalk;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.dingtalk.api.response.OapiSnsGetuserinfoBycodeResponse;
|
||||
import com.dingtalk.api.response.OapiUserGetbyunionidResponse;
|
||||
import com.dingtalk.api.response.OapiV2UserGetResponse;
|
||||
import com.snow.common.core.controller.BaseController;
|
||||
import com.snow.common.core.domain.AjaxResult;
|
||||
import com.snow.common.utils.AuthUtils;
|
||||
import com.snow.common.utils.ServletUtils;
|
||||
import com.snow.common.utils.StringUtils;
|
||||
import com.snow.dingtalk.service.UserService;
|
||||
import com.snow.framework.shiro.auth.LoginType;
|
||||
import com.snow.framework.shiro.auth.UserToken;
|
||||
import com.snow.framework.util.ShiroUtils;
|
||||
import com.snow.system.domain.SysAuthUser;
|
||||
import com.snow.system.domain.SysSocialUser;
|
||||
import com.snow.system.domain.SysUser;
|
||||
import com.snow.system.mapper.SysUserMapper;
|
||||
import com.snow.system.service.ISysConfigService;
|
||||
import com.snow.system.service.impl.SysSocialUserServiceImpl;
|
||||
import com.snow.system.service.impl.SysUserServiceImpl;
|
||||
import me.zhyd.oauth.cache.AuthDefaultStateCache;
|
||||
import me.zhyd.oauth.config.AuthConfig;
|
||||
import me.zhyd.oauth.model.AuthCallback;
|
||||
import me.zhyd.oauth.model.AuthResponse;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
import me.zhyd.oauth.request.AuthDingTalkRequest;
|
||||
import me.zhyd.oauth.request.AuthRequest;
|
||||
import me.zhyd.oauth.utils.AuthStateUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @program: snow
|
||||
|
@ -34,58 +55,118 @@ public class ThirdOauthController extends BaseController {
|
|||
|
||||
@Autowired
|
||||
private ISysConfigService iSysConfigService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private SysUserServiceImpl sysUserService;
|
||||
@Resource
|
||||
private SysUserMapper userMapper;
|
||||
|
||||
|
||||
|
||||
@Autowired
|
||||
private SysSocialUserServiceImpl sysSocialUserService;
|
||||
/**
|
||||
* 跳转钉钉授权页面
|
||||
* 认证授权
|
||||
*
|
||||
* @param source
|
||||
* @throws IOException
|
||||
*/
|
||||
@GetMapping("/toDingPage")
|
||||
public String toDingPage()
|
||||
@GetMapping("/toDingPage/{source}")
|
||||
@ResponseBody
|
||||
public void renderAuth(@PathVariable("source") String source) throws IOException
|
||||
{
|
||||
|
||||
String appId= iSysConfigService.selectConfigByKey("ding.login.appid");
|
||||
StringBuilder url=new StringBuilder("https://oapi.dingtalk.com/connect/qrconnect?appid=");
|
||||
url.append(appId).append("&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=");
|
||||
url.append("http://workflow.vaiwan.com/third/oauth/dingTalkLogin");
|
||||
|
||||
return redirect(url.toString());
|
||||
String appSecret= iSysConfigService.selectConfigByKey("ding.login.appSecret");
|
||||
String url="http://workflow.vaiwan.com/third/oauth/dingTalkLogin";
|
||||
|
||||
AuthRequest authRequest = new AuthDingTalkRequest(AuthConfig.builder()
|
||||
.clientId(appId)
|
||||
.clientSecret(appSecret)
|
||||
.redirectUri(url)
|
||||
.build());
|
||||
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
|
||||
ServletUtils.getResponse().sendRedirect(authorizeUrl);
|
||||
}
|
||||
|
||||
@RequestMapping("/dingTalkLogin")
|
||||
@ResponseBody
|
||||
public AjaxResult dingTalkLogin(String code)
|
||||
/**
|
||||
* 回调结果
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@GetMapping("/auth/callback/{source}")
|
||||
public Object callbackAuth(@PathVariable("source") String source, AuthCallback callback, HttpServletRequest request)
|
||||
{
|
||||
OapiSnsGetuserinfoBycodeResponse.UserInfo userInfoByCode = userService.getUserInfoByCode(code);
|
||||
OapiUserGetbyunionidResponse.UserGetByUnionIdResponse userByUnionId = userService.getUserByUnionId(userInfoByCode.getUnionid());
|
||||
SysUser sysUser = sysUserService.selectUserByDingUserId(userByUnionId.getUserid());
|
||||
SysSocialUser sysSocialUser=new SysSocialUser();
|
||||
sysSocialUser.setCode(code);
|
||||
sysSocialUser.setOpenId(userInfoByCode.getOpenid());
|
||||
sysSocialUser.setUnionId(userInfoByCode.getUnionid());
|
||||
sysSocialUser.setSource("DING_TALK");
|
||||
sysSocialUser.setUserId(sysUser.getUserId());
|
||||
sysSocialUser.setAccessToken(userInfoByCode.getUnionid());
|
||||
//sysSocialUserService.deleteSysSocialUserById(1L);
|
||||
|
||||
if(StringUtils.isNotNull(sysUser)){
|
||||
//todo 登录系统
|
||||
UsernamePasswordToken token = new UsernamePasswordToken(sysUser.getPhonenumber(), sysSocialUser.getUnionId(), false,"2");
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
|
||||
}else {
|
||||
return AjaxResult.error("非企业内用户不允许扫码登录");
|
||||
if (StringUtils.isEmpty(source))
|
||||
{
|
||||
return new ModelAndView("error/unauth");
|
||||
}
|
||||
|
||||
String appId= iSysConfigService.selectConfigByKey("ding.login.appid");
|
||||
String appSecret= iSysConfigService.selectConfigByKey("ding.login.appSecret");
|
||||
String url="http://workflow.vaiwan.com/third/oauth/dingTalkLogin";
|
||||
AuthRequest authRequest = new AuthDingTalkRequest(AuthConfig.builder()
|
||||
.clientId(appId)
|
||||
.clientSecret(appSecret)
|
||||
.redirectUri(url)
|
||||
.build());
|
||||
AuthResponse<AuthUser> response = authRequest.login(callback);
|
||||
if (response.ok())
|
||||
{
|
||||
if (SecurityUtils.getSubject() != null && SecurityUtils.getSubject().getPrincipal() != null)
|
||||
{
|
||||
SysUser user = userMapper.selectAuthUserByUuid(source + response.getData().getUuid());
|
||||
if (StringUtils.isNotNull(user))
|
||||
{
|
||||
return redirect("/index");
|
||||
}
|
||||
// 若已经登录则直接绑定系统账号
|
||||
SysAuthUser authUser = new SysAuthUser();
|
||||
authUser.setAvatar(response.getData().getAvatar());
|
||||
authUser.setUuid(source + response.getData().getUuid());
|
||||
authUser.setUserId(ShiroUtils.getUserId());
|
||||
authUser.setUserName(response.getData().getNickname());
|
||||
authUser.setLoginName(response.getData().getUsername());
|
||||
authUser.setEmail(response.getData().getEmail());
|
||||
authUser.setSource(source);
|
||||
userMapper.insertAuthUser(authUser);
|
||||
return redirect("/index");
|
||||
}
|
||||
SysUser user = userMapper.selectAuthUserByUuid(source + response.getData().getUuid());
|
||||
if (StringUtils.isNotNull(user))
|
||||
{
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
UserToken token = new UserToken(user.getLoginName(), LoginType.NOPASSWD);
|
||||
subject.login(token);
|
||||
return redirect("/index");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ModelAndView("error/bind");
|
||||
}
|
||||
}
|
||||
return new ModelAndView("error/404");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否授权
|
||||
*/
|
||||
@PostMapping("/auth/checkAuthUser")
|
||||
@ResponseBody
|
||||
public AjaxResult checkAuthUser(SysAuthUser authUser)
|
||||
{
|
||||
Long userId = ShiroUtils.getUserId();
|
||||
String source = authUser.getSource();
|
||||
if (userMapper.checkAuthUser(userId, source) > 0)
|
||||
{
|
||||
return error(source + "平台账号已经绑定");
|
||||
}
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消授权
|
||||
*/
|
||||
@PostMapping("/auth/unlock")
|
||||
@ResponseBody
|
||||
public AjaxResult unlockAuth(SysAuthUser authUser)
|
||||
{
|
||||
return toAjax(userMapper.deleteAuthUser(authUser.getAuthId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@ package com.snow.web.controller.system;
|
|||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.snow.framework.shiro.auth.LoginType;
|
||||
import com.snow.framework.shiro.auth.UserToken;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
|
@ -39,7 +42,8 @@ public class SysLoginController extends BaseController
|
|||
@ResponseBody
|
||||
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
|
||||
{
|
||||
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe,"1");
|
||||
//UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe,"1");
|
||||
UserToken token = new UserToken(username, password, LoginType.PASSWORD, rememberMe);
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
try
|
||||
{
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 1024C229.234 1024 0 794.766 0 512S229.234 0 512 0s512 229.234 512 512-229.234 512-512 512z m259.157-568.889l-290.759 0.014c-13.966 0-25.287 11.321-25.287 25.273l-0.028 63.218c0 13.966 11.306 25.287 25.273 25.287H657.38c13.966 0 25.287 11.307 25.287 25.273v12.644a75.847 75.847 0 0 1-75.847 75.847H366.606a25.287 25.287 0 0 1-25.287-25.273v-240.2a75.847 75.847 0 0 1 75.847-75.846l353.92-0.015c13.966 0 25.273-11.306 25.287-25.273l0.071-63.189c0-13.966-11.306-25.287-25.272-25.301l-353.992 0.014c-104.718-0.014-189.624 84.892-189.624 189.61v353.963c0 13.967 11.32 25.287 25.287 25.287h372.935c94.265 0 170.666-76.401 170.666-170.666v-145.38c0-13.952-11.32-25.273-25.287-25.273z" fill="#d81e06" /></svg>
|
After Width: | Height: | Size: 973 B |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M0 520.886c0-69.368 13.51-135.697 40.498-199.02 26.987-63.323 63.322-117.826 109.006-163.51 45.65-45.65 100.154-81.985 163.51-109.006A502.289 502.289 0 0 1 512 8.92c69.335 0 135.663 13.477 198.986 40.497 63.356 26.988 117.86 63.323 163.51 109.007 45.684 45.65 82.02 100.154 109.006 163.51A502.289 502.289 0 0 1 1024 520.852c0 111.318-32.504 211.472-97.511 300.494-64.975 88.989-148.48 150.825-250.484 185.476-5.351 0-9.348-0.99-11.99-2.973-2.676-1.982-4.196-3.997-4.526-6.012a59.458 59.458 0 0 1-0.495-8.984 7.663 7.663 0 0 1-0.991-3.006v-128.99c0-40.63-14.336-75.314-43.008-103.986 76.667-13.345 134.011-41.819 171.999-85.487 37.987-43.669 57.013-96.52 57.013-158.522 0-58.005-18.663-108.346-56.022-150.99 13.345-42.678 11-87.668-6.97-135.003-18.697-1.322-39.011 1.85-61.01 9.513-22 7.663-38.318 14.831-49.02 21.47-10.637 6.673-20.316 13.016-28.97 19.027-38.68-10.669-81.854-16.02-129.486-16.02-47.7 0-90.509 5.351-128.529 16.02-7.333-5.35-15.855-11.164-25.5-17.507-9.68-6.342-26.493-14.005-50.507-22.99-23.982-9.018-45.65-12.85-65.008-11.495-18.663 47.996-20.645 93.646-5.979 136.984-36.665 42.678-54.998 92.986-54.998 150.99 0 62.002 18.663 114.689 55.99 157.994 37.326 43.339 94.67 72.01 171.998 86.016a142.303 142.303 0 0 0-39.969 70.029c-56.683 13.972-96.355 3.963-119.015-30.06-42.017-61.308-79.674-83.307-113.003-65.965-4.69 4.657-3.997 9.48 1.982 14.501 6.012 4.988 14.996 11.66 27.02 19.985 11.99 8.357 20.976 17.507 26.987 27.515 0.661 1.322 2.51 6.177 5.517 14.502a831.917 831.917 0 0 0 8.985 23.981c2.973 7.663 8.654 16.186 17.011 25.5 8.324 9.349 18.003 17.178 29.003 23.52 11 6.309 26.161 11 45.485 14.006 19.324 2.972 41.323 3.138 65.998 0.495v100.484c0 0.991-0.165 2.643-0.495 5.021-0.33 2.312-0.991 3.964-1.982 4.955-0.991 1.024-2.345 2.015-4.03 3.039a12.52 12.52 0 0 1-6.474 1.486c-2.676 0-6.012-0.33-10.009-0.99-101.343-35.345-183.825-97.182-247.51-185.51C31.842 731.037 0 631.577 0 520.92z" /></svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 0C229.2224 0 0 229.21728 0 512s229.2224 512 512 512 512-229.21728 512-512S794.7776 0 512 0z m281.89696 671.57504c-13.22496 12.34432-35.92192-1.10592-57.74336-31.29856a330.44992 330.44992 0 0 1-36.1472 70.30784c30.85312 11.01824 50.69312 28.2112 50.69312 47.61088 0 33.50016-59.2896 60.61056-132.45952 60.61056-43.4176 0-81.77152-9.47712-106.01472-24.2432-24.02304 14.76608-62.592 24.2432-106.01472 24.2432-73.17504 0-132.45952-27.1104-132.45952-60.61056 0-19.1744 19.83488-36.58752 50.69312-47.61088-14.54592-21.16096-26.66496-44.74368-36.14208-70.30784-21.82144 29.97248-44.52352 43.63776-57.74336 31.29856-18.0736-16.9728-11.24352-76.92288 15.64672-133.7856 6.1696-13.0048 12.78464-24.68352 19.61472-34.82112 3.74784-165.30432 112.62976-297.98912 246.19008-297.98912h0.44032c133.56544 0 242.44736 132.45952 246.19008 297.98912 6.8352 10.1376 13.44 21.82144 19.61472 34.82112 26.65984 56.86272 33.7152 116.8128 15.6416 133.7856z" fill="#1296db" /></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1615369931580" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1299" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512 2C230.6 2 2 230.6 2 512s228.6 510 510 510 510-228.6 510-510S793.3 2 512 2z m-93.5 644.3c-24.6 0-49.3-4.3-71.4-10.2-1.7 0-4.3-1.7-4.3-1.7l-55.3 32.3c-14.4 8.5-24.7 1.7-20.4-14.4 0 0 14.4-59.5 11.9-59.5-52.7-34.9-77.4-79.9-77.4-141.1 4.3-102.8 94.4-184.5 216.8-184.5 112.2 0 204 69.7 220.2 161.5h-10.2c-112.2 0-204 77.4-204 173.4 0 16.1 1.7 30.6 6 45h-11.9v-0.8z m328.1 79.9l16.1 32.3c8.5 14.5 1.7 20.4-11.9 11.9 0 0-40.8-24.7-42.5-22.1-18.7 6-59.5 11.9-79.9 11.9-103.7 0-189.6-71.4-189.6-159s85.9-159 189.6-159S818 513.7 818 601.3c0 51.8-26.3 94.3-71.4 124.9zM353 363.3c-8.5-5.1-19.5-5.1-28.9 0-8.5 5.1-14.4 14.4-14.4 24.6s5.1 19.6 14.4 24.7c8.5 5.1 19.6 5.1 28.9 0 8.5-5.1 14.5-14.5 14.5-24.7s-6-19.6-14.5-24.6zM510.3 416c16.2 0 28.9-12.8 28.9-28.9 0-10.2-5.1-19.5-14.4-24.6-8.5-5.1-19.6-5.1-28.9 0-9.3 5.1-14.4 14.4-14.4 24.6-0.1 16.1 12.6 28.9 28.8 28.9z m187 100.3c-13.6 0-24.6 11-24.6 24.6s11 24.6 24.6 24.6 24.7-11 24.7-24.6-11.1-24.6-24.7-24.6z m-134.3 0c-13.6 0-24.6 11-24.6 24.6s11 24.6 24.6 24.6 24.6-11 24.6-24.6-11-24.6-24.6-24.6z" fill="#08BA06" p-id="1300"></path></svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>RuoYi - 403</title>
|
||||
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/style.css}" rel="stylesheet"/>
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="middle-box text-center animated fadeInDown">
|
||||
<h1>500</h1>
|
||||
<h3 class="font-bold">没有绑定注册用户!</h3>
|
||||
|
||||
<div class="error-desc">
|
||||
对不起,您没有绑定注册用户,请先注册后在个人中心绑定第三方授权信息!您可以返回登录页面
|
||||
<a href="javascript:index()" class="btn btn-outline btn-primary btn-xs">返回登录页</a>
|
||||
</div>
|
||||
</div>
|
||||
<script th:inline="javascript">
|
||||
var ctx = [[@{/}]];
|
||||
function index() {
|
||||
window.top.location = ctx + "login";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -15,7 +15,7 @@
|
|||
<!-- 避免IE使用兼容模式 -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="shortcut icon" href="../static/favicon.ico" th:href="@{favicon.ico}"/>
|
||||
<style type="text/css">label.error { position:inherit; }</style>
|
||||
<style type="text/css">label.error{position:inherit}.ui.horizontal.divider::before,.ui.horizontal.divider::after{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC")}.ui.horizontal.divider::after{background-position:left 1em top 50%}.ui.horizontal.divider::before,.ui.horizontal.divider::after{content:'';display:table-cell;position:relative;top:50%;width:50%;background-repeat:no-repeat}.ui.horizontal.divider::before{background-position:right 1em top 50%}.ui.horizontal.list{display:inline-block;font-size:0}ul.ui.list:last-child,ol.ui.list:last-child,.ui.list:last-child{margin-bottom:0;padding-bottom:0}ul.ui.list,ol.ui.list,.ui.list{list-style-type:none;margin:1em 0;padding:0}.login-oauth__list{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.login-login-oauth__container{margin-top:20px}.ui.horizontal.login-login__oauth-title{font-weight:normal}.ui.divider{margin:1.4rem 0rem;line-height:1;height:0;font-weight:bold;text-transform:uppercase;letter-spacing:.05em;color:rgba(0,0,0,0.85);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.ui.horizontal.divider{display:table;white-space:nowrap;height:auto;margin:'';line-height:1;text-align:center}.ui.horizontal.list>.item:first-child,.ui.horizontal.list>.item:last-child{padding-top:.3em;padding-bottom:.3em}.ui.horizontal.list>.item:first-child{margin-left:0!important;padding-left:0!important}.login-oauth__list>.item{margin-left:40px!important}.ui.list .item a>img{width:32px;height:32px}</style>
|
||||
<script>
|
||||
if(window.top!==window.self){alert('未登录或登录超时。请重新登录');window.top.location=window.location};
|
||||
</script>
|
||||
|
@ -61,6 +61,28 @@
|
|||
<input type="checkbox" id="rememberme" name="rememberme"> <label for="rememberme">记住我</label>
|
||||
</div>
|
||||
<button class="btn btn-success btn-block" id="btnSubmit" data-loading="正在验证登录,请稍后...">登录</button>
|
||||
<div class="login-login-oauth__container">
|
||||
<div class="ui horizontal divider login-login__oauth-title">
|
||||
<span class="text-muted">其他方式登录</span>
|
||||
</div>
|
||||
<div class="ui horizontal list login-oauth__list">
|
||||
<div class="item" title="使用 钉钉 账号授权登录">
|
||||
<a th:href="@{/third/oauth/toDingPage/dingtalk}">
|
||||
<img src="../static/img/dingtalk.png" th:src="@{/img/dingtalk.png}"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="item" title="功能开发中...">
|
||||
<a href="#">
|
||||
<img src="../static/img/weixin.svg" th:src="@{/img/weixin.svg}"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="item" title="功能开发中...">
|
||||
<a href="#">
|
||||
<img src="../static/img/qq.svg" th:src="@{/img/qq.svg}"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <a class="btn btn-success btn-block" th:href="@{/third/oauth/toDingPage}" data-loading="正在验证登录,请稍后...">钉钉登录</a>-->
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#user_info" data-toggle="tab" aria-expanded="true">基本资料</a></li>
|
||||
<li><a href="#modify_password" data-toggle="tab" aria-expanded="false">修改密码</a></li>
|
||||
<li><a href="#third_party_binding" data-toggle="tab" aria-expanded="false">第三方帐号绑定</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<!--用户信息-->
|
||||
|
@ -131,6 +132,44 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!--绑定第三方账号登录-->
|
||||
<div class="tab-pane" id="third_party_binding">
|
||||
<div class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
<table id="bootstrap-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-12">
|
||||
<div id="git-user-binding">
|
||||
<h4 class="provider-desc">你可以绑定以下第三方帐号用于DingFlow系统</h4>
|
||||
<div id="authlist" class="user-bind">
|
||||
<a class="third-app" href="#" onclick="authUrl('gitee');" title="使用 Gitee 账号授权登录">
|
||||
<div class="git-other-login-icon"><img th:src="@{/img/gitee.svg}"></div>
|
||||
<span class="app-name">Gitee</span></a>
|
||||
|
||||
<a class="third-app" href="#" onclick="authUrl('github');" title="使用 GitHub 账号授权登录">
|
||||
<div class="git-other-login-icon"><img th:src="@{/img/github.svg}"></div>
|
||||
<span class="app-name">Github</span></a>
|
||||
|
||||
<a class="third-app" href="#" title="功能开发中...">
|
||||
<div class="git-other-login-icon"><img th:src="@{/img/weixin.svg}"></div>
|
||||
<span class="app-name">WeiXin</span></a>
|
||||
|
||||
<a class="third-app" href="#" title="功能开发中...">
|
||||
<div class="git-other-login-icon"><img th:src="@{/img/qq.svg}"></div>
|
||||
<span class="app-name">QQ</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -287,6 +326,91 @@
|
|||
$.operate.saveModal(ctx + "system/user/profile/resetPwd", $('#form-user-resetPwd').serialize());
|
||||
}
|
||||
}
|
||||
|
||||
// 第三方授权列表
|
||||
$(function() {
|
||||
var auths = [[${auths}]]
|
||||
var options = {
|
||||
data: auths,
|
||||
sidePagination: "client",
|
||||
showSearch: false,
|
||||
showRefresh: false,
|
||||
showToggle: false,
|
||||
showColumns: false,
|
||||
pagination: false,
|
||||
columns: [{
|
||||
title: "序号",
|
||||
formatter: function (value, row, index) {
|
||||
return $.table.serialNumber(index);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'source',
|
||||
title: '绑定账号平台'
|
||||
},
|
||||
{
|
||||
field: 'avatar',
|
||||
title: '头像',
|
||||
formatter: function(value, row, index) {
|
||||
return $.table.imageView(value);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'loginName',
|
||||
title: '账号'
|
||||
},
|
||||
{
|
||||
field: 'createTime',
|
||||
title: '绑定时间'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
formatter: function(value, row, index) {
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-danger btn-xs" href="javascript:void(0)" onclick="unlockAuth(this, \'' + row.authId + '\', \'' + row.source + '\')"><i class="fa fa-remove"></i>解除绑定</a>');
|
||||
return actions.join('');
|
||||
}
|
||||
}]
|
||||
};
|
||||
$.table.init(options);
|
||||
});
|
||||
|
||||
// 解除绑定
|
||||
function unlockAuth(obj, authId, source) {
|
||||
$.modal.confirm("您确定要解除" + source + "的账号绑定吗?", function() {
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: ctx + "auth/unlock",
|
||||
data: { "authId": authId },
|
||||
success: function(r) {
|
||||
if (r.code == web_status.SUCCESS) {
|
||||
$(obj).parents("tr").remove();
|
||||
$.modal.msgSuccess("解绑成功");
|
||||
} else {
|
||||
$.modal.msgError(r.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 第三方登录授权
|
||||
function authUrl(source) {
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: ctx + "auth/checkAuthUser",
|
||||
data: { "source": source },
|
||||
success: function(r) {
|
||||
if (r.code == web_status.SUCCESS) {
|
||||
var url = ctx + "auth/" + source;
|
||||
top.location.href =url;
|
||||
} else {
|
||||
$.modal.msgError(r.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -136,6 +136,19 @@
|
|||
<artifactId>jsqlparser</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 第三方授权登录 -->
|
||||
<dependency>
|
||||
<groupId>me.zhyd.oauth</groupId>
|
||||
<artifactId>JustAuth</artifactId>
|
||||
<version>1.15.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- HttpClient -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,149 @@
|
|||
package com.snow.common.utils;
|
||||
|
||||
import me.zhyd.oauth.cache.AuthStateCache;
|
||||
import me.zhyd.oauth.config.AuthConfig;
|
||||
import me.zhyd.oauth.exception.AuthException;
|
||||
import me.zhyd.oauth.request.*;
|
||||
|
||||
/**
|
||||
* 认证授权工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class AuthUtils
|
||||
{
|
||||
@SuppressWarnings("deprecation")
|
||||
public static AuthRequest getAuthRequest(String source, String clientId, String clientSecret, String redirectUri,
|
||||
AuthStateCache authStateCache)
|
||||
{
|
||||
AuthRequest authRequest = null;
|
||||
switch (source.toLowerCase())
|
||||
{
|
||||
case "dingtalk":
|
||||
authRequest = new AuthDingTalkRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "baidu":
|
||||
authRequest = new AuthBaiduRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "github":
|
||||
authRequest = new AuthGithubRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "gitee":
|
||||
authRequest = new AuthGiteeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "weibo":
|
||||
authRequest = new AuthWeiboRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "coding":
|
||||
authRequest = new AuthCodingRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).codingGroupName("").build(), authStateCache);
|
||||
break;
|
||||
case "oschina":
|
||||
authRequest = new AuthOschinaRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "alipay":
|
||||
// 支付宝在创建回调地址时,不允许使用localhost或者127.0.0.1,所以这儿的回调地址使用的局域网内的ip
|
||||
authRequest = new AuthAlipayRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.alipayPublicKey("").redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "qq":
|
||||
authRequest = new AuthQqRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "wechat_open":
|
||||
authRequest = new AuthWeChatOpenRequest(AuthConfig.builder().clientId(clientId)
|
||||
.clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "csdn":
|
||||
authRequest = new AuthCsdnRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "taobao":
|
||||
authRequest = new AuthTaobaoRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "douyin":
|
||||
authRequest = new AuthDouyinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "linkedin":
|
||||
authRequest = new AuthLinkedinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "microsoft":
|
||||
authRequest = new AuthMicrosoftRequest(AuthConfig.builder().clientId(clientId)
|
||||
.clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "mi":
|
||||
authRequest = new AuthMiRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "toutiao":
|
||||
authRequest = new AuthToutiaoRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "teambition":
|
||||
authRequest = new AuthTeambitionRequest(AuthConfig.builder().clientId(clientId)
|
||||
.clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "pinterest":
|
||||
authRequest = new AuthPinterestRequest(AuthConfig.builder().clientId(clientId)
|
||||
.clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "renren":
|
||||
authRequest = new AuthRenrenRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "stack_overflow":
|
||||
authRequest = new AuthStackOverflowRequest(AuthConfig.builder().clientId(clientId)
|
||||
.clientSecret(clientSecret).redirectUri(redirectUri).stackOverflowKey("").build(),
|
||||
authStateCache);
|
||||
break;
|
||||
case "huawei":
|
||||
authRequest = new AuthHuaweiRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "wechat_enterprise":
|
||||
authRequest = new AuthWeChatEnterpriseRequest(AuthConfig.builder().clientId(clientId)
|
||||
.clientSecret(clientSecret).redirectUri(redirectUri).agentId("").build(), authStateCache);
|
||||
break;
|
||||
case "kujiale":
|
||||
authRequest = new AuthKujialeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "gitlab":
|
||||
authRequest = new AuthGitlabRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "meituan":
|
||||
authRequest = new AuthMeituanRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "eleme":
|
||||
authRequest = new AuthElemeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build());
|
||||
break;
|
||||
case "wechat_mp":
|
||||
authRequest = new AuthWeChatMpRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
case "aliyun":
|
||||
authRequest = new AuthAliyunRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
|
||||
.redirectUri(redirectUri).build(), authStateCache);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (null == authRequest)
|
||||
{
|
||||
throw new AuthException("未获取到有效的Auth配置");
|
||||
}
|
||||
return authRequest;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import java.util.LinkedHashMap;
|
|||
import java.util.Map;
|
||||
import javax.servlet.Filter;
|
||||
|
||||
import com.snow.common.constant.Constants;
|
||||
import com.snow.framework.shiro.realm.UserRealm;
|
||||
import com.snow.framework.shiro.session.OnlineSessionDAO;
|
||||
import com.snow.framework.shiro.session.OnlineSessionFactory;
|
||||
|
@ -175,6 +176,7 @@ public class ShiroConfig
|
|||
public UserRealm userRealm(EhCacheManager cacheManager)
|
||||
{
|
||||
UserRealm userRealm = new UserRealm();
|
||||
userRealm.setAuthorizationCacheName(Constants.SYS_AUTH_CACHE);
|
||||
userRealm.setCacheManager(cacheManager);
|
||||
return userRealm;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.snow.framework.shiro.auth;
|
||||
|
||||
/**
|
||||
* 登录类型枚举类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum LoginType
|
||||
{
|
||||
/**
|
||||
* 密码登录
|
||||
*/
|
||||
PASSWORD("password"),
|
||||
/**
|
||||
* 免密码登录
|
||||
*/
|
||||
NOPASSWD("nopasswd");
|
||||
|
||||
private String desc;
|
||||
|
||||
LoginType(String desc)
|
||||
{
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getDesc()
|
||||
{
|
||||
return desc;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.snow.framework.shiro.auth;
|
||||
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
|
||||
/**
|
||||
* 自定义登录Token
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class UserToken extends UsernamePasswordToken
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private LoginType type;
|
||||
|
||||
public UserToken()
|
||||
{
|
||||
}
|
||||
|
||||
public UserToken(String username, String password, LoginType type, boolean rememberMe)
|
||||
{
|
||||
super(username, password, rememberMe);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public UserToken(String username, LoginType type)
|
||||
{
|
||||
super(username, "", false, null);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public UserToken(String username, String password, LoginType type)
|
||||
{
|
||||
super(username, password, false, null);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public LoginType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(LoginType type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,9 @@ package com.snow.framework.shiro.realm;
|
|||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.snow.framework.shiro.auth.LoginType;
|
||||
import com.snow.framework.shiro.auth.UserToken;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
|
@ -14,6 +17,7 @@ import org.apache.shiro.authc.UnknownAccountException;
|
|||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.authz.AuthorizationInfo;
|
||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||
import org.apache.shiro.cache.Cache;
|
||||
import org.apache.shiro.realm.AuthorizingRealm;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -85,9 +89,9 @@ public class UserRealm extends AuthorizingRealm
|
|||
@Override
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
|
||||
{
|
||||
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
|
||||
UserToken upToken = (UserToken) token;
|
||||
String username = upToken.getUsername();
|
||||
String loginType = upToken.getHost();
|
||||
LoginType loginType = upToken.getType();
|
||||
String password = "";
|
||||
if (upToken.getPassword() != null)
|
||||
{
|
||||
|
@ -98,7 +102,12 @@ public class UserRealm extends AuthorizingRealm
|
|||
try
|
||||
{
|
||||
|
||||
user = loginService.login(username, password);
|
||||
if(LoginType.PASSWORD.equals(loginType)){
|
||||
user = loginService.login(username, password);
|
||||
}else if(LoginType.NOPASSWD.equals(loginType)){
|
||||
user = loginService.login(username);
|
||||
}
|
||||
|
||||
}
|
||||
catch (CaptchaException e)
|
||||
{
|
||||
|
@ -140,4 +149,19 @@ public class UserRealm extends AuthorizingRealm
|
|||
{
|
||||
this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理所有用户授权信息缓存
|
||||
*/
|
||||
public void clearAllCachedAuthorizationInfo()
|
||||
{
|
||||
Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
|
||||
if (cache != null)
|
||||
{
|
||||
for (Object key : cache.keys())
|
||||
{
|
||||
cache.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,57 @@ public class SysLoginService
|
|||
recordLoginInfo(user);
|
||||
return user;
|
||||
}
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
public SysUser login(String username)
|
||||
{
|
||||
// 验证码校验
|
||||
if (!StringUtils.isEmpty(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA)))
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
|
||||
throw new CaptchaException();
|
||||
}
|
||||
// 用户名或密码为空 错误
|
||||
if (StringUtils.isEmpty(username))
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
|
||||
throw new UserNotExistsException();
|
||||
}
|
||||
|
||||
// 用户名不在指定范围内 错误
|
||||
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|
||||
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
||||
throw new UserPasswordNotMatchException();
|
||||
}
|
||||
|
||||
// 查询用户信息
|
||||
SysUser user = userService.selectUserByLoginName(username);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
|
||||
throw new UserNotExistsException();
|
||||
}
|
||||
|
||||
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete")));
|
||||
throw new UserDeleteException();
|
||||
}
|
||||
|
||||
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
||||
{
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
|
||||
throw new UserBlockedException();
|
||||
}
|
||||
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
|
||||
recordLoginInfo(user);
|
||||
return user;
|
||||
}
|
||||
private boolean maybeEmail(String username)
|
||||
{
|
||||
if (!username.matches(UserConstants.EMAIL_PATTERN))
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
package com.snow.system.domain;
|
||||
|
||||
import com.snow.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 第三方授权表 sys_auth_user
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysAuthUser extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 授权ID */
|
||||
private Long authId;
|
||||
|
||||
/** 第三方平台用户唯一ID */
|
||||
private String uuid;
|
||||
|
||||
/** 系统用户ID */
|
||||
private Long userId;
|
||||
|
||||
/** 登录账号 */
|
||||
private String loginName;
|
||||
|
||||
/** 用户昵称 */
|
||||
private String userName;
|
||||
|
||||
/** 头像地址 */
|
||||
private String avatar;
|
||||
|
||||
/** 用户邮箱 */
|
||||
private String email;
|
||||
|
||||
/** 用户来源 */
|
||||
private String source;
|
||||
|
||||
public Long getAuthId()
|
||||
{
|
||||
return authId;
|
||||
}
|
||||
|
||||
public void setAuthId(Long authId)
|
||||
{
|
||||
this.authId = authId;
|
||||
}
|
||||
|
||||
public String getUuid()
|
||||
{
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid)
|
||||
{
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public Long getUserId()
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getLoginName()
|
||||
{
|
||||
return loginName;
|
||||
}
|
||||
|
||||
public void setLoginName(String loginName)
|
||||
{
|
||||
this.loginName = loginName;
|
||||
}
|
||||
|
||||
public String getUserName()
|
||||
{
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName)
|
||||
{
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getAvatar()
|
||||
{
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public void setAvatar(String avatar)
|
||||
{
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
public String getEmail()
|
||||
{
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email)
|
||||
{
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(String source)
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.snow.system.mapper;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.snow.system.domain.SysAuthUser;
|
||||
import com.snow.system.domain.SysUser;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
@ -145,4 +146,46 @@ public interface SysUserMapper
|
|||
* @return 结果
|
||||
*/
|
||||
public SysUser checkEmailUnique(String email);
|
||||
|
||||
|
||||
/**
|
||||
* 根据uuid查询用户信息
|
||||
*
|
||||
* @param uuid 唯一信息
|
||||
* @return 结果
|
||||
*/
|
||||
public SysUser selectAuthUserByUuid(String uuid);
|
||||
|
||||
/**
|
||||
* 新增第三方授权信息
|
||||
*
|
||||
* @param authUser 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertAuthUser(SysAuthUser authUser);
|
||||
|
||||
/**
|
||||
* 根据用户编号查询授权列表
|
||||
*
|
||||
* @param loginName 登录账户
|
||||
* @return 授权列表
|
||||
*/
|
||||
public List<SysAuthUser> selectAuthUserListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 校验source平台是否绑定
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param source 绑定平台
|
||||
* @return 结果
|
||||
*/
|
||||
public int checkAuthUser(@Param("userId") Long userId, @Param("source") String source);
|
||||
|
||||
/**
|
||||
* 根据编号删除第三方授权信息
|
||||
*
|
||||
* @param authId 授权编号
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteAuthUser(Long authId);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.snow.system.service;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.snow.system.domain.SysAuthUser;
|
||||
import com.snow.system.domain.SysUser;
|
||||
import com.snow.system.domain.SysUserRole;
|
||||
|
||||
|
@ -220,4 +221,11 @@ public interface ISysUserService
|
|||
* @return 结果
|
||||
*/
|
||||
public int changeStatus(SysUser user);
|
||||
/**
|
||||
* 根据用户编号查询授权列表
|
||||
*
|
||||
* @param userId 登录账户
|
||||
* @return 授权列表
|
||||
*/
|
||||
public List<SysAuthUser> selectAuthUserListByUserId(Long userId);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import com.snow.common.enums.DingTalkListenerType;
|
||||
import com.snow.system.domain.SysUserPost;
|
||||
import com.snow.system.domain.SysUserRole;
|
||||
import com.snow.system.domain.*;
|
||||
import com.snow.system.event.SyncEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -20,9 +19,6 @@ import com.snow.common.core.text.Convert;
|
|||
import com.snow.common.exception.BusinessException;
|
||||
import com.snow.common.utils.StringUtils;
|
||||
import com.snow.common.utils.security.Md5Utils;
|
||||
import com.snow.system.domain.SysPost;
|
||||
import com.snow.system.domain.SysRole;
|
||||
import com.snow.system.domain.SysUser;
|
||||
import com.snow.system.mapper.SysPostMapper;
|
||||
import com.snow.system.mapper.SysRoleMapper;
|
||||
import com.snow.system.mapper.SysUserMapper;
|
||||
|
@ -543,4 +539,15 @@ public class SysUserServiceImpl implements ISysUserService
|
|||
{
|
||||
return userMapper.updateUser(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户编号查询授权列表
|
||||
*
|
||||
* @param userId 登录账户
|
||||
* @return 授权列表
|
||||
*/
|
||||
public List<SysAuthUser> selectAuthUserListByUserId(Long userId)
|
||||
{
|
||||
return userMapper.selectAuthUserListByUserId(userId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="dataScope" column="data_scope" />
|
||||
<result property="status" column="role_status" />
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="SysAuthUserResult" type="SysAuthUser">
|
||||
<id property="authId" column="auth_id" />
|
||||
<result property="uuid" column="uuid" />
|
||||
<result property="userId" column="user_id" />
|
||||
<result property="loginName" column="login_name" />
|
||||
<result property="userName" column="user_name" />
|
||||
<result property="avatar" column="avatar" />
|
||||
<result property="email" column="email" />
|
||||
<result property="source" column="source" />
|
||||
<result property="createTime" column="create_time" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectUserVo">
|
||||
select u.user_id, u.dept_id, u.login_name, u.user_name, u.user_type, u.email, u.avatar, u.phonenumber, u.sex, u.password, u.salt, u.status, u.del_flag, u.login_ip, u.login_date, u.pwd_update_date, u.create_time, u.remark,
|
||||
|
@ -286,5 +298,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
|
||||
<select id="selectAuthUserListByUserId" parameterType="Long" resultMap="SysAuthUserResult">
|
||||
select auth_id, uuid, user_id, login_name, user_name, avatar, email, source, create_time
|
||||
from sys_auth_user where user_id = #{userId}
|
||||
</select>
|
||||
|
||||
<select id="selectAuthUserByUuid" parameterType="String" resultMap="SysUserResult">
|
||||
select b.user_id as user_id, b.login_name as login_name, b.password as password
|
||||
from sys_auth_user a left join sys_user b on a.user_id = b.user_id
|
||||
where a.uuid = #{uuid} and b.del_flag = '0'
|
||||
</select>
|
||||
|
||||
<select id="checkAuthUser" parameterType="SysAuthUser" resultType="int">
|
||||
select count(1) from sys_auth_user where user_id=#{userId} and source=#{source} limit 1
|
||||
</select>
|
||||
|
||||
<insert id="insertAuthUser" parameterType="SysAuthUser">
|
||||
insert into sys_auth_user(
|
||||
<if test="uuid != null and uuid != ''">uuid,</if>
|
||||
<if test="userId != null and userId != 0">user_id,</if>
|
||||
<if test="loginName != null and loginName != ''">login_name,</if>
|
||||
<if test="userName != null and userName != ''">user_name,</if>
|
||||
<if test="avatar != null and avatar != ''">avatar,</if>
|
||||
<if test="email != null and email != ''">email,</if>
|
||||
<if test="source != null and source != ''">source,</if>
|
||||
create_time
|
||||
)values(
|
||||
<if test="uuid != null and uuid != ''">#{uuid},</if>
|
||||
<if test="userId != null and userId != 0">#{userId},</if>
|
||||
<if test="loginName != null and loginName != ''">#{loginName},</if>
|
||||
<if test="userName != null and userName != ''">#{userName},</if>
|
||||
<if test="avatar != null and avatar != ''">#{avatar},</if>
|
||||
<if test="email != null and email != ''">#{email},</if>
|
||||
<if test="source != null and source != ''">#{source},</if>
|
||||
sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
<delete id="deleteAuthUser" parameterType="Long">
|
||||
delete from sys_auth_user where auth_id = #{authId}
|
||||
</delete>
|
||||
|
||||
</mapper>
|
Loading…
Reference in New Issue