增加企业微信登录调整。

This commit is contained in:
bo.yang 2021-07-28 23:17:08 +08:00
parent 3828b0e262
commit 5af0efb50f
7 changed files with 128 additions and 55 deletions

View File

@ -2,10 +2,14 @@ package com.ruoyi.web.controller.system;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.ruoyi.framework.shiro.util.CustToken;
import com.ruoyi.system.service.IWechatApiService;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -15,6 +19,8 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import java.util.Map;
/** /**
* 登录验证 * 登录验证
* *
@ -23,23 +29,40 @@ import com.ruoyi.common.utils.StringUtils;
@Controller @Controller
public class SysLoginController extends BaseController public class SysLoginController extends BaseController
{ {
@Autowired
private IWechatApiService wechatApiService;
@GetMapping("/login") @GetMapping("/login")
public String login(HttpServletRequest request, HttpServletResponse response) public String login(HttpServletRequest request, HttpServletResponse response, Map<String,String> map)
{ {
String loginType= request.getParameter("loginType");
if(StringUtils.isNotEmpty(loginType) && request.getParameter("loginType").equals("wechat")){
String code= request.getParameter("code");
//String state = request.getParameter("state");
String username=wechatApiService.GetLoginNameWithWechatCode(code);
String password="";
Boolean rememberMe=true;
map.put("loginType","wechat");
map.put("username",username);
map.put("password",password);
return "login";
}
// 如果是Ajax请求返回Json字符串 // 如果是Ajax请求返回Json字符串
if (ServletUtils.isAjaxRequest(request)) if (ServletUtils.isAjaxRequest(request))
{ {
return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}"); return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
} }
return "login"; return "login";
} }
@PostMapping("/login") @PostMapping("/login")
@ResponseBody @ResponseBody
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe) public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe,String loginType)
{ {
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe); // UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
CustToken token=new CustToken(username,password,rememberMe,loginType);
Subject subject = SecurityUtils.getSubject(); Subject subject = SecurityUtils.getSubject();
try try
{ {

View File

@ -1,20 +1,19 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.framework.shiro.util.CustToken;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.IWechatApiService; import com.ruoyi.system.service.IWechatApiService;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; 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 javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -22,39 +21,31 @@ import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.List;
import java.util.Map; import java.util.Map;
@RestController @Controller
public class WechatApiController extends BaseController { public class WechatApiController extends BaseController {
@Autowired @Autowired
IWechatApiService wechatApiService; IWechatApiService wechatApiService;
@RequestMapping("anon/getAccessToken") @RequestMapping("anon/getAccessToken")
public String getAccessToken() { public String getAccessToken() {
return wechatApiService.GetAccessToken(); return wechatApiService.GetAccessToken();
} }
@GetMapping("anon/wechatLogin") @GetMapping("anon/wechatLogin")
@ResponseBody @ResponseBody
public AjaxResult WechatLogin(HttpServletRequest request) public AjaxResult WechatLogin(HttpServletRequest request)
{ {
String code= request.getParameter("code"); String code= request.getParameter("code");
//String state = request.getParameter("state"); String state = request.getParameter("state");
String username=wechatApiService.GetLoginNameWithWechatCode(code); String username=wechatApiService.GetLoginNameWithWechatCode(code);
String password=code; String password="";
String rememberMe="0"; Boolean rememberMe=true;
String loginType=request.getParameter("loginType");
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe); //UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
CustToken token=new CustToken(username,password,rememberMe,loginType);
Subject subject = SecurityUtils.getSubject(); Subject subject = SecurityUtils.getSubject();
try try
{ {
@ -71,7 +62,6 @@ public class WechatApiController extends BaseController {
return error(msg); return error(msg);
} }
} }
@GetMapping("anon/userInfo") @GetMapping("anon/userInfo")

View File

@ -44,8 +44,8 @@
<form id="signupForm" autocomplete="off"> <form id="signupForm" autocomplete="off">
<h4 class="no-margins">登录:</h4> <h4 class="no-margins">登录:</h4>
<p class="m-t-md">请输入用户名、密码进行登录!</p> <p class="m-t-md">请输入用户名、密码进行登录!</p>
<input type="text" name="username" class="form-control uname" placeholder="用户名" value="admin" /> <input type="text" name="username" class="form-control uname" placeholder="用户名" />
<input type="password" name="password" class="form-control pword" placeholder="密码" value="admin123" /> <input type="password" name="password" class="form-control pword" placeholder="密码" />
<div class="row m-t" th:if="${captchaEnabled==true}"> <div class="row m-t" th:if="${captchaEnabled==true}">
<div class="col-xs-6"> <div class="col-xs-6">
<input type="text" name="validateCode" class="form-control code" placeholder="验证码" maxlength="5" /> <input type="text" name="validateCode" class="form-control code" placeholder="验证码" maxlength="5" />
@ -81,5 +81,38 @@
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script> <script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.2}"></script> <script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.2}"></script>
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script> <script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
<script th:inline="javascript">
var loginType = [[${loginType}]];
var username = [[${username}]];
var password = [[${password}]];
var validateCode = $("input[name='validateCode']").val();
var rememberMe = "true";
$(function () {
if (loginType == 'wechat') {
$.ajax({
type: "post",
url: ctx + "login",
data: {
"username": username,
"password": password,
"validateCode": validateCode,
"rememberMe": rememberMe,
"loginType": loginType
},
success: function(r) {
if (r.code == web_status.SUCCESS) {
location.href = ctx + 'index';
} else {
$.modal.closeLoading();
$('.imgcode').click();
$(".code").val("");
$.modal.msg(r.msg);
}
}
});
}
});
</script>
</body> </body>
</html> </html>

View File

@ -2,6 +2,8 @@ package com.ruoyi.framework.shiro.realm;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import com.ruoyi.framework.shiro.util.CustToken;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.AuthenticationToken;
@ -86,9 +88,12 @@ public class UserRealm extends AuthorizingRealm
@Override @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
{ {
UsernamePasswordToken upToken = (UsernamePasswordToken) token; //UsernamePasswordToken upToken = (UsernamePasswordToken) token;
CustToken upToken= (CustToken) token;
String loginType = upToken.getLoginType();
String username = upToken.getUsername(); String username = upToken.getUsername();
String password = ""; String password = "";
if (upToken.getPassword() != null) if (upToken.getPassword() != null)
{ {
password = new String(upToken.getPassword()); password = new String(upToken.getPassword());
@ -97,7 +102,7 @@ public class UserRealm extends AuthorizingRealm
SysUser user = null; SysUser user = null;
try try
{ {
user = loginService.login(username, password); user = loginService.login(username, password,loginType);
} }
catch (CaptchaException e) catch (CaptchaException e)
{ {

View File

@ -38,26 +38,26 @@ public class SysLoginService
/** /**
* 登录 * 登录
*/ */
public SysUser login(String username, String password) public SysUser login(String username, String password,String loginType)
{ {
// 验证码校验 //如果是企业微信登录则无需验证本密码规则
if (ShiroConstants.CAPTCHA_ERROR.equals(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA))) if(StringUtils.isEmpty(loginType) || !loginType.equals("wechat")) {
{ // 验证码校验
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); if (ShiroConstants.CAPTCHA_ERROR.equals(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA))) {
throw new CaptchaException(); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
} throw new CaptchaException();
// 用户名或密码为空 错误 }
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) // 用户名或密码为空 错误
{ if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
throw new UserNotExistsException(); throw new UserNotExistsException();
} }
// 密码如果不在指定范围内 错误 // 密码如果不在指定范围内 错误
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH) || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
{ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); throw new UserPasswordNotMatchException();
throw new UserPasswordNotMatchException(); }
} }
// 用户名不在指定范围内 错误 // 用户名不在指定范围内 错误
@ -88,20 +88,22 @@ public class SysLoginService
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
throw new UserNotExistsException(); throw new UserNotExistsException();
} }
if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete")));
throw new UserDeleteException(); throw new UserDeleteException();
} }
if (UserStatus.DISABLE.getCode().equals(user.getStatus())) if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark()))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
throw new UserBlockedException(); throw new UserBlockedException();
} }
//如果是企业微信登录则无需本地验证密码
passwordService.validate(user, password); if(StringUtils.isEmpty(loginType) || !loginType.equals("wechat")){
passwordService.validate(user, password);
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
recordLoginInfo(user); recordLoginInfo(user);

View File

@ -0,0 +1,20 @@
package com.ruoyi.framework.shiro.util;
import org.apache.shiro.authc.UsernamePasswordToken;
public class CustToken extends UsernamePasswordToken {
private String loginType;// 企业微信wechat
public String getLoginType() {
return loginType;
}
public void setLoginType(String loginType) {
this.loginType = loginType;
}
public CustToken(String username, String password, Boolean rememberMe, String loginType) {
super(username, password);
this.loginType = loginType;
}
}

View File

@ -112,8 +112,8 @@ public class WechatApiServiceImpl implements IWechatApiService {
//获取访问用户身份ID //获取访问用户身份ID
String url="https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo"; String url="https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo";
String param = "access_token="+wechatApiService.GetAccessToken()+"&code="+code; String param = "access_token="+wechatApiService.GetAccessToken()+"&code="+code;
//String userInfo = HttpUtils.sendGet(url,param); //测试已能正常返回UserInfo Json,正式使用时打开 String userInfo = HttpUtils.sendGet(url,param); //测试已能正常返回UserInfo Json,正式使用时打开
String userInfo = "{\"UserId\":\"359\",\"DeviceId\":\"10000589102865WJ\",\"errcode\":0,\"errmsg\":\"ok\"}"; //为避免去微信获取code麻烦开发调试时打开 //String userInfo = "{\"UserId\":\"359\",\"DeviceId\":\"10000589102865WJ\",\"errcode\":0,\"errmsg\":\"ok\"}"; //为避免去微信获取code麻烦开发调试时打开
JSONObject jsonObjectUserInfo = JSONObject.parseObject(userInfo); JSONObject jsonObjectUserInfo = JSONObject.parseObject(userInfo);
//如果返回码不为0则返回错误信息 //如果返回码不为0则返回错误信息
if ( Integer.parseInt(jsonObjectUserInfo.getString("errcode")) != 0){ if ( Integer.parseInt(jsonObjectUserInfo.getString("errcode")) != 0){