| @@ -9,7 +9,6 @@ import com.iformall.domain.po.*; | |||
| import com.iformall.domain.vo.MallUserInfoVo; | |||
| import com.iformall.enums.EnumMallUserStatus; | |||
| import com.iformall.enums.EnumMsgModel; | |||
| import com.iformall.enums.EnumUserWechat; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.service.*; | |||
| import com.iformall.shiro.UserSession; | |||
| @@ -103,10 +102,20 @@ public class HomeController extends BaseController { | |||
| // throw new SystemException(ErrorCode.LOGIN_USER_OR_PWD_ERROR); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| boolean isLogin = false; | |||
| try { | |||
| Subject subject = SecurityUtils.getSubject(); | |||
| UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword()); | |||
| subject.login(token); | |||
| isLogin = true; | |||
| } catch (MallinkException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(ErrorCode.USER_PASSWD_ERR); | |||
| } | |||
| if(isLogin) { | |||
| MallUserInfo info = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); | |||
| info.setPassword("保密"); | |||
| if(StringUtils.isNotBlank(info.getBopenId())) | |||
| @@ -120,14 +129,17 @@ public class HomeController extends BaseController { | |||
| info.setMenus(menus); | |||
| } | |||
| String cookieName = URLEncoder.encode(info.getUsername(), "utf-8"); | |||
| Cookie unameCookie = new Cookie("uname", cookieName); | |||
| unameCookie.setMaxAge(3600); | |||
| response.addCookie(unameCookie); | |||
| try { | |||
| String cookieName = URLEncoder.encode(info.getUsername(), "utf-8"); | |||
| Cookie unameCookie = new Cookie("uname", cookieName); | |||
| unameCookie.setMaxAge(3600); | |||
| response.addCookie(unameCookie); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| data.data = info; | |||
| } catch (Exception e) { | |||
| return new ResultData(ErrorCode.USER_PASSWD_ERR); | |||
| } | |||
| return data; | |||
| } | |||
| @@ -194,7 +206,11 @@ public class HomeController extends BaseController { | |||
| response.addCookie(unameCookie); | |||
| data.data = info; | |||
| } catch (MallinkException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(ErrorCode.USER_PASSWD_ERR); | |||
| } | |||
| return data; | |||
| @@ -252,40 +268,43 @@ public class HomeController extends BaseController { | |||
| if(userList.size() == 1) { | |||
| MallUserInfoVo user = userList.get(0); | |||
| // check 验证码正确 | |||
| boolean isValidCode = false; | |||
| try { | |||
| boolean isValidCode = mallUserInfoService.checkCodeValid(user, code); | |||
| if(isValidCode) { | |||
| // 验证码正确,直接登录 | |||
| try { | |||
| Subject subject = SecurityUtils.getSubject(); | |||
| UseriFormallToken token = new UseriFormallToken(user.getUsername()); | |||
| subject.login(token); | |||
| MallUserInfo info = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); | |||
| info.setPassword("保密"); | |||
| if(StringUtils.isNotBlank(info.getBopenId())) | |||
| info.setBopenId("保密"); | |||
| if(StringUtils.isNotBlank(info.getWebOpenId())) { | |||
| info.setWebOpenId("保密"); | |||
| } | |||
| String menus = mallUserRoleService.getPermissionsByUser(info); | |||
| if(menus != null) { | |||
| info.setMenus(menus); | |||
| } | |||
| isValidCode = mallUserInfoService.checkCodeValid(user, code); | |||
| } catch (Exception e) { | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| if(isValidCode) { | |||
| // 验证码正确,直接登录 | |||
| try { | |||
| Subject subject = SecurityUtils.getSubject(); | |||
| UseriFormallToken token = new UseriFormallToken(user.getUsername()); | |||
| subject.login(token); | |||
| MallUserInfo info = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); | |||
| info.setPassword("保密"); | |||
| if(StringUtils.isNotBlank(info.getBopenId())) | |||
| info.setBopenId("保密"); | |||
| if(StringUtils.isNotBlank(info.getWebOpenId())) { | |||
| info.setWebOpenId("保密"); | |||
| } | |||
| String menus = mallUserRoleService.getPermissionsByUser(info); | |||
| if(menus != null) { | |||
| info.setMenus(menus); | |||
| } | |||
| String cookieName = URLEncoder.encode(info.getUsername(), "utf-8"); | |||
| Cookie unameCookie = new Cookie("uname", cookieName); | |||
| unameCookie.setMaxAge(3600); | |||
| response.addCookie(unameCookie); | |||
| String cookieName = URLEncoder.encode(info.getUsername(), "utf-8"); | |||
| Cookie unameCookie = new Cookie("uname", cookieName); | |||
| unameCookie.setMaxAge(3600); | |||
| response.addCookie(unameCookie); | |||
| return new ResultData(info); | |||
| } catch (Exception e) { | |||
| return new ResultData(ErrorCode.USER_PASSWD_ERR); | |||
| } | |||
| } else { | |||
| return new ResultData(ErrorCode.MSG_VERIFY_CODE_NOT_FOUND); | |||
| return new ResultData(info); | |||
| } catch (MallinkException e) { | |||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| return new ResultData(ErrorCode.USER_PASSWD_ERR); | |||
| } | |||
| } catch (Exception e) { | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } else { | |||
| return new ResultData(ErrorCode.MSG_VERIFY_CODE_NOT_FOUND); | |||
| } | |||
| } else { | |||
| return new ResultData(ErrorCode.USER_IS_EMPTY); | |||
| @@ -2,10 +2,12 @@ package com.iformall.controller; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import com.iformall.domain.vo.MallUserInfoVo; | |||
| import com.iformall.enums.EnumUserAdmin; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.service.MallUserInfoService; | |||
| import com.iformall.service.MallUserRoleService; | |||
| import com.iformall.shiro.UserSession; | |||
| @@ -20,7 +22,6 @@ import me.chanjar.weixin.common.error.WxErrorException; | |||
| import me.chanjar.weixin.mp.api.WxMpService; | |||
| import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||
| import me.chanjar.weixin.mp.bean.result.WxMpUser; | |||
| import net.sf.saxon.trans.Err; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.shiro.SecurityUtils; | |||
| import org.apache.shiro.subject.Subject; | |||
| @@ -36,7 +37,9 @@ import javax.servlet.http.HttpServletResponse; | |||
| import java.io.IOException; | |||
| import java.net.URLEncoder; | |||
| import java.util.ArrayList; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.concurrent.TimeUnit; | |||
| @@ -84,22 +87,30 @@ public class WechatLoginController extends BaseController { | |||
| log.debug(mpUser.toString()); | |||
| } | |||
| // 保存 openId 到 cookie,一小时过期 | |||
| //Cookie openIdCookie = new Cookie("openId", accessToken.getOpenId()); | |||
| //openIdCookie.setMaxAge(60); | |||
| //response.addCookie(openIdCookie); | |||
| // check user openid 是否是已授权用户 | |||
| List<MallUserInfoVo> userList = mallUserInfoService.getUsersByWebOpenId(accessToken.getOpenId()); | |||
| log.info("login user list count " + userList.size()); | |||
| if(userList.size() > 0) { | |||
| if(userList.size() == 1) { | |||
| Map<String, Object> ret = new HashMap<>(); | |||
| // 唯一用户 | |||
| MallUserInfo user = userList.get(0); | |||
| boolean isLogin = false; | |||
| try { | |||
| Subject subject = SecurityUtils.getSubject(); | |||
| UseriFormallToken token = new UseriFormallToken(user.getUsername()); | |||
| subject.login(token); | |||
| isLogin = true; | |||
| } catch (MallinkException e) { | |||
| log.error(e.getMessage()); | |||
| ret.put("code", e.getErrorCode()); | |||
| ret.put("message", e.getMessage()); | |||
| } catch (Exception e) { | |||
| log.error(e.getMessage()); | |||
| ret.put("code", Result.ERROR); | |||
| ret.put("message", e.getMessage()); | |||
| } | |||
| if(isLogin) { | |||
| MallUserInfo info = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); | |||
| info.setPassword("保密"); | |||
| info.setBopenId("保密"); | |||
| @@ -110,14 +121,38 @@ public class WechatLoginController extends BaseController { | |||
| if(menus != null) { | |||
| info.setMenus(menus); | |||
| } | |||
| String cookieName = URLEncoder.encode(info.getUsername(), "utf-8"); | |||
| Cookie unameCookie = new Cookie("uname", cookieName); | |||
| unameCookie.setMaxAge(3600); | |||
| response.addCookie(unameCookie); | |||
| response.sendRedirect("https://" + host + "/#/layout"); | |||
| } catch (Exception e) { | |||
| log.error(e.getMessage()); | |||
| try { | |||
| String cookieName = URLEncoder.encode(info.getUsername(), "utf-8"); | |||
| Cookie unameCookie = new Cookie("uname", cookieName); | |||
| unameCookie.setMaxAge(3600); | |||
| response.addCookie(unameCookie); | |||
| } catch (Exception e) { | |||
| log.error(e.getMessage()); | |||
| ret.put("code", Result.ERROR); | |||
| ret.put("message", e.getMessage()); | |||
| } | |||
| Object codeObj = ret.get("code"); | |||
| if(codeObj == null) { | |||
| try { | |||
| response.sendRedirect("https://" + host + "/#/logout"); | |||
| } catch (Exception e) { | |||
| log.error(e.getMessage()); | |||
| } | |||
| } else { | |||
| try { | |||
| String errCode = URLEncoder.encode(JSON.toJSONString(ret), "utf-8"); | |||
| response.sendRedirect("https://" + host + "/#/login?errcode=" + errCode); | |||
| } catch (Exception e) { | |||
| log.error(e.getMessage()); | |||
| } | |||
| } | |||
| } else { | |||
| try { | |||
| String errCode = URLEncoder.encode(JSON.toJSONString(ret), "utf-8"); | |||
| response.sendRedirect("https://" + host + "/#/login?errcode="+errCode); | |||
| } catch (Exception e) { | |||
| log.error(e.getMessage()); | |||
| } | |||
| } | |||
| } else { | |||
| // 跳转登录选择页面 | |||
| @@ -144,8 +179,11 @@ public class WechatLoginController extends BaseController { | |||
| } | |||
| } else { | |||
| // 跳转登录页面 | |||
| Map<String, Object> ret = new HashMap<>(); | |||
| ret.put("code", ErrorCode.WECHAT_LOGIN_NOT_BIND.getCode()); | |||
| ret.put("message", ErrorCode.WECHAT_LOGIN_NOT_BIND.getMessage()); | |||
| try { | |||
| String errCode = URLEncoder.encode("您的微信未绑定", "utf-8"); | |||
| String errCode = URLEncoder.encode(JSON.toJSONString(ret), "utf-8"); | |||
| response.sendRedirect("https://" + host + "/#/login?errcode="+errCode); | |||
| } catch (Exception e) { | |||
| log.error(e.getMessage()); | |||
| @@ -180,6 +218,7 @@ public class WechatLoginController extends BaseController { | |||
| MallUserInfo userInfo = mallUserInfoService.getByUsername(userName); | |||
| if(userInfo.getWebOpenId().equals(openId)) { | |||
| boolean isLogin = false; | |||
| try { | |||
| Subject subject = SecurityUtils.getSubject(); | |||
| UseriFormallToken token = new UseriFormallToken(userInfo.getUsername()); | |||
| @@ -201,8 +240,12 @@ public class WechatLoginController extends BaseController { | |||
| response.addCookie(unameCookie); | |||
| return new ResultData(); | |||
| } catch (MallinkException e) { | |||
| log.error(e.getMessage()); | |||
| return new ResultData(e.getErrorCode(), e.getMessage()); | |||
| } catch (Exception e) { | |||
| log.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } else { | |||
| // 登录失败 | |||
| @@ -218,6 +261,7 @@ public class WechatLoginController extends BaseController { | |||
| public void userBindWebOpenId(String code, String state, HttpServletRequest request, HttpServletResponse response) { | |||
| log.debug("[" + getIpAddr() + "] WechatLoginController::bindWebOpenId"); | |||
| String host = request.getHeader("host"); | |||
| String errCode = null; | |||
| try { | |||
| WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code); | |||
| log.debug("accessToken: " + accessToken.getAccessToken() + ", openId: " + accessToken.getOpenId() + ", unionId: " + accessToken.getUnionId()); | |||
| @@ -228,11 +272,6 @@ public class WechatLoginController extends BaseController { | |||
| log.debug(mpUser.toString()); | |||
| } | |||
| // 保存 openId 到 cookie,一小时过期 | |||
| Cookie openIdCookie = new Cookie("openId", accessToken.getOpenId()); | |||
| openIdCookie.setMaxAge(60); | |||
| response.addCookie(openIdCookie); | |||
| String uname = state; | |||
| MallUserInfo user = mallUserInfoService.getByUsername(uname); | |||
| if(user != null) { | |||
| @@ -242,13 +281,24 @@ public class WechatLoginController extends BaseController { | |||
| response.sendRedirect("https://" + host + "/#/layout"); | |||
| } else { | |||
| log.debug("https://" + host + "/#/layout?errcode=绑定失败"); | |||
| String errCode = URLEncoder.encode("绑定失败", "utf-8"); | |||
| errCode = URLEncoder.encode("绑定失败", "utf-8"); | |||
| response.sendRedirect("https://" + host + "/#/layout?errcode="+errCode); | |||
| } | |||
| } catch (WxErrorException e) { | |||
| log.error(e.getMessage()); | |||
| errCode = e.getMessage(); | |||
| } catch (IOException e) { | |||
| log.error(e.getMessage()); | |||
| errCode = e.getMessage(); | |||
| } | |||
| if(StringUtils.isNotBlank(errCode)) { | |||
| try { | |||
| errCode = URLEncoder.encode(errCode, "utf-8"); | |||
| response.sendRedirect("https://" + host + "/#/layout?errcode="+errCode); | |||
| } catch (Exception e) { | |||
| log.error(e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| @@ -266,6 +316,7 @@ public class WechatLoginController extends BaseController { | |||
| if(userInfo.getId() == null && userInfo.getUsername() == null) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| // 只有本人及超级管理员可以解绑微信 | |||
| if(userInfo.getId().equals(user.getId()) | |||
| || user.getIsAdmin().equals(EnumUserAdmin.ADMIN.getCode())) { | |||
| mallUserInfoService.cleanWebOpenId(userInfo); | |||
| @@ -1,18 +1,38 @@ | |||
| package com.iformall.shiro; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import com.iformall.enums.EnumLoginType; | |||
| import com.iformall.enums.EnumMallUserStatus; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.service.MallUserInfoService; | |||
| import org.apache.shiro.authc.AuthenticationInfo; | |||
| import org.apache.shiro.authc.AuthenticationToken; | |||
| import org.apache.shiro.authc.credential.HashedCredentialsMatcher; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import javax.annotation.Resource; | |||
| @Configuration | |||
| public class MyRetryLimitCredentialsMatcher extends HashedCredentialsMatcher { | |||
| @Resource | |||
| private MallUserInfoService userService; | |||
| @Override | |||
| public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) { | |||
| if(authcToken instanceof UseriFormallToken) { | |||
| UseriFormallToken tk = (UseriFormallToken) authcToken; | |||
| if(tk.getType().equals(EnumLoginType.NOPASSWD)){ | |||
| // 获取用户的输入的账号. | |||
| String username = (String)tk.getPrincipal(); | |||
| MallUserInfo user = userService.getByUsername(username); | |||
| if(user == null) { | |||
| throw new MallinkException(ErrorCode.USER_IS_EMPTY); | |||
| } | |||
| // 用户被禁用 | |||
| if(user.getStatus()==null ||!EnumMallUserStatus.VALID.getCode().equals(user.getStatus())) { | |||
| throw new MallinkException(ErrorCode.USER_IS_LOCKED); | |||
| } | |||
| return true; | |||
| } | |||
| boolean matches = super.doCredentialsMatch(authcToken, info); | |||
| @@ -2,7 +2,9 @@ package com.iformall.shiro; | |||
| import javax.annotation.Resource; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.enums.EnumMallUserStatus; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.service.MallUserInfoService; | |||
| import org.apache.shiro.SecurityUtils; | |||
| import org.apache.shiro.authc.AuthenticationException; | |||
| @@ -53,11 +55,11 @@ public class MyShiroRealm extends AuthorizingRealm { | |||
| String username = (String)token.getPrincipal(); | |||
| MallUserInfo user = userService.getByUsername(username); | |||
| if(user == null) { | |||
| throw new UnknownAccountException("用户名不存在"); | |||
| throw new MallinkException(ErrorCode.USER_IS_EMPTY); | |||
| } | |||
| if(user.getStatus()==null || | |||
| !EnumMallUserStatus.VALID.getCode().equals(user.getStatus())) {//用户被禁用 | |||
| throw new UnknownAccountException("用户被禁用"); | |||
| throw new MallinkException(ErrorCode.USER_IS_LOCKED); | |||
| } | |||
| SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( | |||
| user, //用户 | |||
| @@ -27,17 +27,6 @@ public enum ErrorCode{ | |||
| SYS_EXTEND_JSON_ERROR(1012, "JSON格式异常"), | |||
| SYS_REPEAT_SUBMIT_EXCEPTION(1013, "请勿重复操作"), | |||
| /** | |||
| * 审批流 | |||
| */ | |||
| FLOW_FAIL(24000, "审批流操作出错"), | |||
| /** | |||
| * 审批流不存在 | |||
| */ | |||
| FLOW_INST_NOT_EXIST(24001, "任务不存在"), | |||
| /** | |||
| * 数据库 | |||
| */ | |||
| @@ -69,7 +58,6 @@ public enum ErrorCode{ | |||
| USER_USE_ROLE(1994,"用户使用此角色"), | |||
| USER_IS_EMPTY(2000, "用户不存在"), | |||
| PASSWORD_ERROR(2001, "密码错误"), | |||
| LOGIN_USER_OR_PWD_ERROR(2002, "用户名或密码错误"), | |||
| USER_IS_LOCKED(2003, "用户已经被锁定不能登录,请与管理员联系"), | |||
| NEW_USER_FAILD(2004, "创建新用户失败"), | |||
| BUSER_NOT_IN_APP(2005, "用户不是此app用户"), | |||
| @@ -339,21 +327,28 @@ public enum ErrorCode{ | |||
| WIWIDE_INFO_NOT_FOUND(23001,"迈外迪信息未找到"), | |||
| WIWIDE_INFO_NOT_READY(23002,"迈外迪信息未就绪"), | |||
| /** | |||
| * 审批流 | |||
| */ | |||
| FLOW_FAIL(24000, "审批流操作出错"), | |||
| FLOW_INST_NOT_EXIST(24001, "任务不存在"), | |||
| /** | |||
| * 微信第三方 | |||
| */ | |||
| WEAPP_APPID_NOT_AUTH(24000, "appid未授权"), | |||
| WEAPP_BASIC_SET_ERR(24001, "基础配置错误"), | |||
| WEAPP_BASIC_SET_DOMAIN_ERR(24002, "基础服务器域名配置错误"), | |||
| WEAPP_EXT_SET_ERR(24003, "扩展配置错误"), | |||
| WEAPP_CODE_COMMIT_ERR(24004, "code提交失败"), | |||
| WEAPP_AUDIT_ERR(24005, "提交审核失败"), | |||
| WEAPP_HAD_AUDITING(24006, "已有审核中"), | |||
| WEAPP_NOT_AUDITED(24007, "审核未通过"), | |||
| WEAPP_APP_RELEASEED(24008, "已发布"), | |||
| WECHAT_LOGIN_KEY_OVERTIME(24030, "已过期"), | |||
| WECHAT_LOGIN_USER_SELECT(24031, "请选择要登录的用户"), | |||
| WEAPP_APPID_NOT_AUTH(24100, "appid未授权"), | |||
| WEAPP_BASIC_SET_ERR(24101, "基础配置错误"), | |||
| WEAPP_BASIC_SET_DOMAIN_ERR(24102, "基础服务器域名配置错误"), | |||
| WEAPP_EXT_SET_ERR(24103, "扩展配置错误"), | |||
| WEAPP_CODE_COMMIT_ERR(24104, "code提交失败"), | |||
| WEAPP_AUDIT_ERR(24105, "提交审核失败"), | |||
| WEAPP_HAD_AUDITING(24106, "已有审核中"), | |||
| WEAPP_NOT_AUDITED(24107, "审核未通过"), | |||
| WEAPP_APP_RELEASEED(24108, "已发布"), | |||
| WECHAT_LOGIN_KEY_OVERTIME(24130, "已过期"), | |||
| WECHAT_LOGIN_USER_SELECT(24131, "请选择要登录的用户"), | |||
| WECHAT_LOGIN_NOT_BIND(24132, "您的微信号未绑定,请登录后绑定"), | |||
| /** | |||
| * 屏广告 | |||