/**
* Copyright © 2015-2020 JeePlus All rights reserved.
*/
package com.jeeplus.modules.sys.security;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import com.jeeplus.common.config.Global;
import com.jeeplus.common.servlet.ValidateCodeServlet;
import com.jeeplus.common.utils.Encodes;
import com.jeeplus.common.utils.SpringContextHolder;
import com.jeeplus.common.web.Servlets;
import com.jeeplus.modules.sys.entity.Menu;
import com.jeeplus.modules.sys.entity.Role;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.service.SystemService;
import com.jeeplus.modules.sys.utils.LogUtils;
import com.jeeplus.modules.sys.utils.UserUtils;
import com.jeeplus.modules.sys.web.LoginController;
/**
* 系统安全认证实现类
* @author jeeplus
* @version 2014-7-5
*/
@Service
//@DependsOn({"userDao","roleDao","menuDao"})
public class SystemAuthorizingRealm extends AuthorizingRealm {
private Logger logger = LoggerFactory.getLogger(getClass());
private SystemService systemService;
@Autowired
HttpServletRequest request;
/**
* 认证回调函数, 登录时调用
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
int activeSessionSize = getSystemService().getSessionDao().getActiveSessions(false).size();
if (logger.isDebugEnabled()){
logger.debug("login submit, active session size: {}, username: {}", activeSessionSize, token.getUsername());
}
boolean mobile = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_MOBILE_PARAM);
// 校验登录验证码
if (!mobile && LoginController.isValidateCodeLogin(token.getUsername(), false, false)){
Session session = UserUtils.getSession();
String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)){
throw new AuthenticationException("msg:验证码错误, 请重试.");
}
}
// 校验用户名密码
User user = getSystemService().getUserByLoginName(token.getUsername());
if (user != null) {
if (Global.NO.equals(user.getLoginFlag())){
throw new AuthenticationException("msg:该已帐号禁止登录.");
}
byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
return new SimpleAuthenticationInfo(new Principal(user, token.isMobileLogin()),
user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
} else {
return null;
}
}
/**
* 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Principal principal = (Principal) getAvailablePrincipal(principals);
// 获取当前已登录的用户
if (!Global.TRUE.equals(Global.getConfig("user.multiAccountLogin"))){
Collection sessions = getSystemService().getSessionDao().getActiveSessions(true, principal, UserUtils.getSession());
if (sessions.size() > 0){
// 如果是登录进来的,则踢出已在线用户
if (UserUtils.getSubject().isAuthenticated()){
for (Session session : sessions){
getSystemService().getSessionDao().delete(session);
}
}
// 记住我进来的,并且当前用户已登录,则退出当前用户提示信息。
else{
UserUtils.getSubject().logout();
throw new AuthenticationException("msg:账号已在其它地方登录,请重新登录。");
}
}
}
User user = getSystemService().getUserByLoginName(principal.getLoginName());
if (user != null) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
List