多次调用登录接口,允许改变登录身份,无需退出再登录

This commit is contained in:
thinkgem
2020-04-13 22:56:40 +08:00
parent d1da0fb299
commit aee477551e
2 changed files with 108 additions and 69 deletions

View File

@@ -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<String, Object> 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<String, Object> getLoginData(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> data = MapUtils.newHashMap();
// 获取登录参数
Map<String, Object> paramMap = ServletUtils.getExtParams(request);
for (Entry<String, Object> 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<String, Object> getLoginFailureData(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> 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<String, Object> paramMap = ServletUtils.getExtParams(request);
for (Entry<String, Object> 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;
}
}

View File

@@ -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<String, Object> paramMap = ServletUtils.getExtParams(request);
// 如果登录设置了语言,则切换语言
if (paramMap.get("lang") != null){
Global.setLang((String)paramMap.get("lang"), request, response);
}
// 获取登录失败数据
Map<String, Object> 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<String, Object> 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<String, Object> paramMap = ServletUtils.getExtParams(request);
for (Entry<String, Object> 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";
}
/**