From 5af0efb50f694602a7dc2e47cd68a032447f36a5 Mon Sep 17 00:00:00 2001 From: "bo.yang" Date: Wed, 28 Jul 2021 23:17:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E7=99=BB=E5=BD=95=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/system/SysLoginController.java | 31 ++++++++++-- .../system/WechatApiController.java | 34 +++++-------- .../src/main/resources/templates/login.html | 37 +++++++++++++- .../framework/shiro/realm/UserRealm.java | 9 +++- .../shiro/service/SysLoginService.java | 48 ++++++++++--------- .../ruoyi/framework/shiro/util/CustToken.java | 20 ++++++++ .../service/impl/WechatApiServiceImpl.java | 4 +- 7 files changed, 128 insertions(+), 55 deletions(-) create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/util/CustToken.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index 1652f74ef..fb8f8dc6c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -2,10 +2,14 @@ package com.ruoyi.web.controller.system; import javax.servlet.http.HttpServletRequest; 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.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.PostMapping; @@ -15,6 +19,8 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; +import java.util.Map; + /** * 登录验证 * @@ -23,23 +29,40 @@ import com.ruoyi.common.utils.StringUtils; @Controller public class SysLoginController extends BaseController { + @Autowired + private IWechatApiService wechatApiService; + @GetMapping("/login") - public String login(HttpServletRequest request, HttpServletResponse response) + public String login(HttpServletRequest request, HttpServletResponse response, Map 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字符串。 if (ServletUtils.isAjaxRequest(request)) { return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}"); } - return "login"; } @PostMapping("/login") @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(); try { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/WechatApiController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/WechatApiController.java index c2b773b62..5898a1cfa 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/WechatApiController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/WechatApiController.java @@ -1,20 +1,19 @@ package com.ruoyi.web.controller.system; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.core.controller.BaseController; 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.http.HttpUtils; -import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.framework.shiro.util.CustToken; import com.ruoyi.system.service.IWechatApiService; 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.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.http.HttpServletRequest; @@ -22,39 +21,31 @@ import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.util.List; import java.util.Map; -@RestController +@Controller public class WechatApiController extends BaseController { @Autowired IWechatApiService wechatApiService; - - @RequestMapping("anon/getAccessToken") public String getAccessToken() { return wechatApiService.GetAccessToken(); } - - - - - - - @GetMapping("anon/wechatLogin") @ResponseBody public AjaxResult WechatLogin(HttpServletRequest request) { String code= request.getParameter("code"); - //String state = request.getParameter("state"); + String state = request.getParameter("state"); String username=wechatApiService.GetLoginNameWithWechatCode(code); - String password=code; - String rememberMe="0"; + String password=""; + 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(); try { @@ -71,7 +62,6 @@ public class WechatApiController extends BaseController { return error(msg); } - } @GetMapping("anon/userInfo") diff --git a/ruoyi-admin/src/main/resources/templates/login.html b/ruoyi-admin/src/main/resources/templates/login.html index 7f13bfaba..4083cfa7f 100644 --- a/ruoyi-admin/src/main/resources/templates/login.html +++ b/ruoyi-admin/src/main/resources/templates/login.html @@ -44,8 +44,8 @@

登录:

请输入用户名、密码进行登录!

- - + +
@@ -81,5 +81,38 @@ + diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java index 8cda35e2d..88ad4d249 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java @@ -2,6 +2,8 @@ package com.ruoyi.framework.shiro.realm; import java.util.HashSet; import java.util.Set; + +import com.ruoyi.framework.shiro.util.CustToken; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; @@ -86,9 +88,12 @@ public class UserRealm extends AuthorizingRealm @Override 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 password = ""; + if (upToken.getPassword() != null) { password = new String(upToken.getPassword()); @@ -97,7 +102,7 @@ public class UserRealm extends AuthorizingRealm SysUser user = null; try { - user = loginService.login(username, password); + user = loginService.login(username, password,loginType); } catch (CaptchaException e) { diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/service/SysLoginService.java index e729ff714..2b60bd489 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/service/SysLoginService.java @@ -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))) - { - AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); - throw new CaptchaException(); - } - // 用户名或密码为空 错误 - if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) - { - AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); - throw new UserNotExistsException(); - } - // 密码如果不在指定范围内 错误 - if (password.length() < UserConstants.PASSWORD_MIN_LENGTH - || password.length() > UserConstants.PASSWORD_MAX_LENGTH) - { - AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); - throw new UserPasswordNotMatchException(); + //如果是企业微信登录,则无需验证本密码规则 + if(StringUtils.isEmpty(loginType) || !loginType.equals("wechat")) { + // 验证码校验 + if (ShiroConstants.CAPTCHA_ERROR.equals(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) || StringUtils.isEmpty(password)) { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); + throw new UserNotExistsException(); + } + // 密码如果不在指定范围内 错误 + if (password.length() < UserConstants.PASSWORD_MIN_LENGTH + || password.length() > UserConstants.PASSWORD_MAX_LENGTH) { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } } // 用户名不在指定范围内 错误 @@ -88,20 +88,22 @@ public class SysLoginService 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(); } - - 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"))); recordLoginInfo(user); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/util/CustToken.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/util/CustToken.java new file mode 100644 index 000000000..9c00686e8 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/util/CustToken.java @@ -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; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatApiServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatApiServiceImpl.java index 27152e025..14d685ce2 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatApiServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatApiServiceImpl.java @@ -112,8 +112,8 @@ public class WechatApiServiceImpl implements IWechatApiService { //获取访问用户身份ID String url="https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo"; String param = "access_token="+wechatApiService.GetAccessToken()+"&code="+code; - //String userInfo = HttpUtils.sendGet(url,param); //测试已能正常返回UserInfo Json,正式使用时打开 - String userInfo = "{\"UserId\":\"359\",\"DeviceId\":\"10000589102865WJ\",\"errcode\":0,\"errmsg\":\"ok\"}"; //为避免去微信获取code麻烦,开发调试时打开 + String userInfo = HttpUtils.sendGet(url,param); //测试已能正常返回UserInfo Json,正式使用时打开 + //String userInfo = "{\"UserId\":\"359\",\"DeviceId\":\"10000589102865WJ\",\"errcode\":0,\"errmsg\":\"ok\"}"; //为避免去微信获取code麻烦,开发调试时打开 JSONObject jsonObjectUserInfo = JSONObject.parseObject(userInfo); //如果返回码不为0,则返回错误信息 if ( Integer.parseInt(jsonObjectUserInfo.getString("errcode")) != 0){