From aee477551e141f4b75b064b6a3df6d34508c815a Mon Sep 17 00:00:00 2001 From: thinkgem Date: Mon, 13 Apr 2020 22:56:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E6=AC=A1=E8=B0=83=E7=94=A8=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=85=81=E8=AE=B8=E6=94=B9?= =?UTF-8?q?=E5=8F=98=E7=99=BB=E5=BD=95=E8=BA=AB=E4=BB=BD=EF=BC=8C=E6=97=A0?= =?UTF-8?q?=E9=9C=80=E9=80=80=E5=87=BA=E5=86=8D=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/FormAuthenticationFilter.java | 98 ++++++++++++++++++- .../modules/sys/web/LoginController.java | 79 +++------------ 2 files changed, 108 insertions(+), 69 deletions(-) diff --git a/modules/core/src/main/java/com/jeesite/common/shiro/filter/FormAuthenticationFilter.java b/modules/core/src/main/java/com/jeesite/common/shiro/filter/FormAuthenticationFilter.java index f1648f24..7511e475 100644 --- a/modules/core/src/main/java/com/jeesite/common/shiro/filter/FormAuthenticationFilter.java +++ b/modules/core/src/main/java/com/jeesite/common/shiro/filter/FormAuthenticationFilter.java @@ -5,6 +5,7 @@ package com.jeesite.common.shiro.filter; import java.io.IOException; import java.util.Map; +import java.util.Map.Entry; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -15,6 +16,8 @@ import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; +import org.apache.shiro.authz.UnauthorizedException; +import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.apache.shiro.web.servlet.Cookie; import org.apache.shiro.web.servlet.SimpleCookie; @@ -24,6 +27,7 @@ import org.slf4j.LoggerFactory; import com.jeesite.common.codec.DesUtils; import com.jeesite.common.codec.EncodeUtils; +import com.jeesite.common.collect.MapUtils; import com.jeesite.common.config.Global; import com.jeesite.common.lang.ObjectUtils; import com.jeesite.common.lang.StringUtils; @@ -31,13 +35,14 @@ import com.jeesite.common.network.IpUtils; import com.jeesite.common.shiro.authc.FormToken; import com.jeesite.common.shiro.realm.BaseAuthorizingRealm; import com.jeesite.common.shiro.realm.LoginInfo; +import com.jeesite.common.web.CookieUtils; import com.jeesite.common.web.http.ServletUtils; import com.jeesite.modules.sys.utils.UserUtils; /** * 表单验证(包含验证码)过滤类 * @author ThinkGem - * @version 2018-7-11 + * @version 2020-4-13 */ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter { @@ -159,6 +164,14 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc. return captcha; } + /** + * 多次调用登录接口,允许改变登录身份,无需退出再登录 + */ + @Override + protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { + return (!isLoginRequest(request, response) && isPermissive(mappedValue)); // 不验证登录状态,只验证登录请求 + } + /** * 跳转登录页时,跳转到默认首页 */ @@ -256,10 +269,93 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc. } request.setAttribute(getFailureKeyAttribute(), className); request.setAttribute(DEFAULT_MESSAGE_PARAM, message); + + // 登录操作如果是Ajax操作,直接返回登录信息字符串。 + if (ServletUtils.isAjaxRequest(((HttpServletRequest) request))){ + Map data = getLoginFailureData(((HttpServletRequest) request), ((HttpServletResponse) response)); + ServletUtils.renderResult(((HttpServletResponse) response), Global.TRUE, message, data); + return false; + } + return true; } public void setAuthorizingRealm(BaseAuthorizingRealm authorizingRealm) { this.authorizingRealm = authorizingRealm; } + + public static Map getLoginData(HttpServletRequest request, HttpServletResponse response) { + Map data = MapUtils.newHashMap(); + + // 获取登录参数 + Map paramMap = ServletUtils.getExtParams(request); + for (Entry entry : paramMap.entrySet()){ + data.put(DEFAULT_PARAM_PREFIX_PARAM + entry.getKey(), entry.getValue()); + } + + // 如果已登录,再次访问主页,则退出原账号。 + if (!Global.TRUE.equals(Global.getConfig("shiro.isAllowRefreshIndex"))){ + CookieUtils.setCookie(response, "LOGINED", "false"); + } + + // 是否显示验证码 + data.put("isValidCodeLogin", Global.getConfigToInteger("sys.login.failedNumAfterValidCode", "200") == 0); + + //获取当前会话对象 + Session session = UserUtils.getSession(); + data.put("sessionid", (String)session.getId()); + + // 如果登录设置了语言,则切换语言 + if (paramMap.get("lang") != null){ + Global.setLang((String)paramMap.get("lang"), request, response); + } + + data.put("result", "login"); + return data; + } + + public static Map getLoginFailureData(HttpServletRequest request, HttpServletResponse response) { + Map data = MapUtils.newHashMap(); + + String username = WebUtils.getCleanParam(request, DEFAULT_USERNAME_PARAM); + boolean rememberMe = WebUtils.isTrue(request, DEFAULT_REMEMBER_ME_PARAM); + boolean rememberUserCode = WebUtils.isTrue(request, DEFAULT_REMEMBER_USERCODE_PARAM); + String params = WebUtils.getCleanParam(request, DEFAULT_PARAMS_PARAM); + String exception = (String)request.getAttribute(DEFAULT_ERROR_KEY_ATTRIBUTE_NAME); + String message = (String)request.getAttribute(DEFAULT_MESSAGE_PARAM); + + String secretKey = Global.getProperty("shiro.loginSubmit.secretKey"); + if (StringUtils.isNotBlank(secretKey)){ + username = DesUtils.decode(username, secretKey); + } + + data.put(DEFAULT_USERNAME_PARAM, username); + data.put(DEFAULT_REMEMBER_ME_PARAM, rememberMe); + data.put(DEFAULT_REMEMBER_USERCODE_PARAM, rememberUserCode); + data.put(DEFAULT_PARAMS_PARAM, params); + Map paramMap = ServletUtils.getExtParams(request); + for (Entry entry : paramMap.entrySet()){ + data.put(DEFAULT_PARAM_PREFIX_PARAM + entry.getKey(), entry.getValue()); + } + data.put(DEFAULT_ERROR_KEY_ATTRIBUTE_NAME, exception); + data.put(DEFAULT_MESSAGE_PARAM, message); + + // 非授权异常,登录失败,验证码加1。 + if (!UnauthorizedException.class.getName().equals(exception)){ + data.put("isValidCodeLogin", BaseAuthorizingRealm.isValidCodeLogin(username, + (String)paramMap.get("corpCode"), (String)paramMap.get("deviceType"), "failed")); + } + + //获取当前会话对象 + Session session = UserUtils.getSession(); + data.put("sessionid", (String)session.getId()); + + // 如果登录设置了语言,则切换语言 + if (paramMap.get("lang") != null){ + Global.setLang((String)paramMap.get("lang"), request, response); + } + + data.put("result", Global.FALSE); + return data; + } } \ No newline at end of file diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/LoginController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/LoginController.java index 23b5addb..9068ae34 100644 --- a/modules/core/src/main/java/com/jeesite/modules/sys/web/LoginController.java +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/LoginController.java @@ -5,14 +5,12 @@ package com.jeesite.modules.sys.web; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.AuthorizationInfo; -import org.apache.shiro.authz.UnauthorizedException; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; @@ -25,11 +23,9 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.fasterxml.jackson.annotation.JsonView; -import com.jeesite.common.codec.DesUtils; import com.jeesite.common.config.Global; import com.jeesite.common.lang.StringUtils; import com.jeesite.common.shiro.filter.FormAuthenticationFilter; -import com.jeesite.common.shiro.realm.BaseAuthorizingRealm; import com.jeesite.common.shiro.realm.LoginInfo; import com.jeesite.common.web.BaseController; import com.jeesite.common.web.CookieUtils; @@ -42,7 +38,7 @@ import com.jeesite.modules.sys.utils.UserUtils; /** * 登录Controller * @author ThinkGem - * @version 2017-03-25 + * @version 2020-4-13 */ @Controller @RequestMapping(value = "${adminPath}") @@ -76,35 +72,18 @@ public class LoginController extends BaseController{ return loginFailure(request, response, model); } - // 如果已登录,再次访问主页,则退出原账号。 - if (!Global.TRUE.equals(Global.getConfig("shiro.isAllowRefreshIndex"))){ - CookieUtils.setCookie(response, "LOGINED", "false"); - } - - // 是否显示验证码 - model.addAttribute("isValidCodeLogin", Global.getConfigToInteger("sys.login.failedNumAfterValidCode", "200") == 0); - - //获取当前会话对象 - Session session = UserUtils.getSession(); - model.addAttribute("sessionid", (String)session.getId()); - - // 获取登录参数 - Map paramMap = ServletUtils.getExtParams(request); - - // 如果登录设置了语言,则切换语言 - if (paramMap.get("lang") != null){ - Global.setLang((String)paramMap.get("lang"), request, response); - } + // 获取登录失败数据 + Map data = FormAuthenticationFilter.getLoginData(request, response); + model.addAllAttributes(data); // 如果是Ajax请求,返回Json字符串。 if (ServletUtils.isAjaxRequest((HttpServletRequest)request)){ - model.addAttribute("result", "login"); model.addAttribute("message", text("sys.login.notLongIn")); return ServletUtils.renderObject(response, model); } // 返回指定用户类型的登录页视图 - String userType = (String)paramMap.get("userType"); + String userType = (String)data.get(FormAuthenticationFilter.DEFAULT_PARAM_PREFIX_PARAM + "userType"); if (StringUtils.isBlank(userType)){ userType = User.USER_TYPE_EMPLOYEE; } @@ -131,53 +110,17 @@ public class LoginController extends BaseController{ return null; } - String username = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_USERNAME_PARAM); - boolean rememberMe = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM); - boolean rememberUserCode = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_REMEMBER_USERCODE_PARAM); - String params = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_PARAMS_PARAM); - String exception = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME); - String message = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM); - - String secretKey = Global.getProperty("shiro.loginSubmit.secretKey"); - if (StringUtils.isNotBlank(secretKey)){ - username = DesUtils.decode(username, secretKey); - } + // 获取登录失败数据 + Map data = FormAuthenticationFilter.getLoginFailureData(request, response); + model.addAllAttributes(data); - model.addAttribute(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM, username); - model.addAttribute(FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM, rememberMe); - model.addAttribute(FormAuthenticationFilter.DEFAULT_REMEMBER_USERCODE_PARAM, rememberUserCode); - model.addAttribute(FormAuthenticationFilter.DEFAULT_PARAMS_PARAM, params); - Map paramMap = ServletUtils.getExtParams(request); - for (Entry entry : paramMap.entrySet()){ - model.addAttribute(FormAuthenticationFilter.DEFAULT_PARAM_PREFIX_PARAM + entry.getKey(), entry.getValue()); - } - model.addAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME, exception); - - // 如果登录设置了语言,则切换语言 - if (paramMap.get("lang") != null){ - Global.setLang((String)paramMap.get("lang"), request, response); - } - - model.addAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM, text(message)); - - // 非授权异常,登录失败,验证码加1。 - if (!UnauthorizedException.class.getName().equals(exception)){ - model.addAttribute("isValidCodeLogin", BaseAuthorizingRealm.isValidCodeLogin(username, - (String)paramMap.get("corpCode"), (String)paramMap.get("deviceType"), "failed")); - } - - //获取当前会话对象 - Session session = UserUtils.getSession(); - model.addAttribute("sessionid", (String)session.getId()); - - // 登录操作如果是Ajax操作,直接返回登录信息字符串。 + // 如果是Ajax请求,返回Json字符串。 if (ServletUtils.isAjaxRequest(request)){ - model.addAttribute("result", Global.FALSE); return ServletUtils.renderObject(response, model); } // 返回指定用户类型的登录页视图 - String userType = (String)paramMap.get("userType"); + String userType = (String)data.get(FormAuthenticationFilter.DEFAULT_PARAM_PREFIX_PARAM + "userType"); if (StringUtils.isBlank(userType)){ userType = User.USER_TYPE_EMPLOYEE; } @@ -404,7 +347,7 @@ public class LoginController extends BaseController{ CookieUtils.setCookie(response, "skinName_" + loginInfo.getId(), skinName); return REDIRECT + adminPath + "/index"; } - return "modules/sys/switchSkin"; + return "modules/sys/sysSwitchSkin"; } /**