/** * 所有请求都会经过的方法。 */ @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { //会在这里调用认证 } /* * 主要是针对登入成功的处理方法。对于请求头是AJAX的之间返回JSON字符串。 */ @Override protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception { //在这里写登入成功的处理,如需要在登陆成功后返回的数据 }
/** * 主要是处理登入失败的方法 */ @Override protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { if (!isAjaxRequest((HttpServletRequest) request)) { //在这里写登入失败的处理,如需要在登陆失败后返回的数据 }
import com.aliyun.openservices.shade.com.alibaba.fastjson.JSONObject;
import com.sinochem.erp.common.entity.MaterialCategory;
import com.sinochem.erp.common.entity.Org;
import com.sinochem.erp.common.entity.Permissions;
import com.sinochem.erp.common.entity.User;
import com.sinochem.erp.security.exception.IncorrectCaptchaException;
import com.sinochem.erp.service.OrgService;
import com.sinochem.erp.service.UserService;
import com.sinochem.erp.service.impmain.MaterialCategoryService;
import com.sinochem.erp.service.impmain.PermissionsServcie;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by topcat on 2017/4/10.
*/
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
public static final String DEFAULT_CAPTCHA_PARAM = "captcha";
private String captchaParam = DEFAULT_CAPTCHA_PARAM;
private UserService userService;
private MaterialCategoryService materialCategoryMapper;
private PermissionsServcie permissionsServcie;
private OrgService orgService;
private static final Logger log = LoggerFactory.getLogger(CaptchaFormAuthenticationFilter.class);
public CaptchaFormAuthenticationFilter(UserService userService, MaterialCategoryService materialCategoryMapper, PermissionsServcie permissionsServcie,OrgService orgService) {
this.userService = userService;
this.materialCategoryMapper = materialCategoryMapper;
this.permissionsServcie = permissionsServcie;
this.orgService=orgService;
}
public String getCaptchaParam() {
return captchaParam;
}
public void setCaptchaParam(String captchaParam) {
this.captchaParam = captchaParam;
}
protected String getCaptcha(ServletRequest request) {
return WebUtils.getCleanParam(request, getCaptchaParam());
}
// 创建 Token
protected CaptchaUsernamePasswordToken createToken(
ServletRequest request, ServletResponse response) {
//获取手机类型
HttpServletRequest httpServletRequest =(HttpServletRequest) request;
String platforms = httpServletRequest.getHeader("platforms");
String username = getUsername(request);
String password = getPassword(request);
String captcha = getCaptcha(request);
// boolean rememberMe = isRememberMe(request);
boolean rememberMe = true;
String host = getHost(request);
return new CaptchaUsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha,platforms);
}
// 验证码校验
protected void doCaptchaValidate(HttpServletRequest request, CaptchaUsernamePasswordToken token) {
String captcha = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
if (captcha != null && !captcha.equalsIgnoreCase(token.getCaptcha())) {
throw new IncorrectCaptchaException("验证码错误!");
}
}
// 认证
protected boolean executeLogin(ServletRequest request,
ServletResponse response) throws Exception {
CaptchaUsernamePasswordToken token = createToken(request, response);
try {
//暂不需要做验证码校验
//doCaptchaValidate((HttpServletRequest) request, token);
Subject subject = getSubject(request, response);
subject.login(token);
//认证成功
return onLoginSuccess(token, subject, request, response);
} catch (AuthenticationException e) {
//认证失败
return onLoginFailure(token, e, request, response);
}
}
public class CaptchaUsernamePasswordToken extends UsernamePasswordToken {
private String captcha;
private String platforms;
public String getPlatforms() {
return platforms;
}
public void setPlatforms(String platforms) {
this.platforms = platforms;
}
public String getCaptcha() {
return captcha;
}
public void setCaptcha(String captcha) {
this.captcha = captcha;
}
public CaptchaUsernamePasswordToken(String username, char[] password,
boolean rememberMe, String host, String captcha,String platforms) {
super(username, password, rememberMe, host);
this.captcha = captcha;
this.platforms=platforms;
}
}
/*
* 主要是针对登入成功的处理方法。对于请求头是AJAX的之间返回JSON字符串。
* 可在这定义一些登陆成功时返回的数据
*/
@Override
protected boolean onLoginSuccess(AuthenticationToken token,
Subject subject, ServletRequest request, ServletResponse response)
throws Exception {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
User user = (User) subject.getPrincipal();
recordLastLoginTime(user);
//初始化数据
initSession();
//获取权限
initPermissions(user);
if (!isAjaxRequest((HttpServletRequest) request)) {// 不是ajax请求
issueSuccessRedirect(request, response);
} else {
httpServletResponse.setCharacterEncoding("UTF-8");
PrintWriter out = httpServletResponse.getWriter();
JSONObject j = new JSONObject();
initJson(subject, user, j);
out.println(j.toJSONString());
out.flush();
out.close();
}
return false;
}
private void initJson(Subject subject, User user, JSONObject j) {
j.put("status", "200");
j.put("message", "登入成功");
j.put("success", true);
User newUser = new User();
try {
BeanUtils.copyProperties(newUser, user);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
newUser.setPwd(null);
newUser.setSalt(null);
Session session = subject.getSession();
List list = (List) session.getAttribute("permissions");
Map map = new HashMap();
map.put("User", newUser);
map.put("Permissions", list);
Org parentOrg=orgService.getParent(user.getOrgCode());
map.put("parent",parentOrg);
j.put("data", map);
}
private void initSession() {
Session session = SecurityUtils.getSubject().getSession();
Map map = new HashMap();
//获取UDC 对应的Unit汉字名称
initUDC(session, map);
}
private void initUDC(Session session, Map map) {
MaterialCategory materialCategory = new MaterialCategory();
materialCategory.setCode("00");
materialCategory.setUserCode("UM");
List materialCategories = materialCategoryMapper.getMaterialCategorys(materialCategory);
Map udc = new HashMap<>();
materialCategories.forEach(materialCategorie -> {
if (StringUtils.isNotBlank(materialCategorie.getCustomCode())) {
udc.put(materialCategorie.getCustomCode(), materialCategorie.getRemark());
}
});
map.put("UDC", udc);
session.setAttribute("UDC", map);
}
private void initPermissions(User user) {
Session session = SecurityUtils.getSubject().getSession();
List permissionsList = permissionsServcie.getPermissionsByuser(user.getId());
/* Map permissionMap = new HashMap<>();
permissionsList.forEach(permission -> {
if (StringUtils.isNotBlank(permission.getName())) {
permissionMap.put(permission.getName(),permission.getCode());
}
});*/
// map.put("permissions", permissionMap);
session.setAttribute("permissions", permissionsList);
}
private void recordLastLoginTime(User user) {
// user.setLastLoginTime(new Date());
userService.updateById(user);
}
/**
* 主要是处理登入失败的方法
*/
@Override
protected boolean onLoginFailure(AuthenticationToken token,
AuthenticationException e, ServletRequest request,
ServletResponse response) {
if (!isAjaxRequest((HttpServletRequest) request)) {// 不是ajax请求
setFailureAttribute(request, e);
return true;
}
try {
response.setCharacterEncoding("UTF-8");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
PrintWriter out = response.getWriter();
String message = e.getClass().getSimpleName();
String res = "";
if (e.getCause() != null) {
res = e.getCause().getClass().getSimpleName();
}
if ("IncorrectCredentialsException".equals(message)) {
out.println("{\"success\":false,\"message\":\"密码错误\",\"status\":500}");
} else if ("UnknownAccountException".equals(message)) {
out.println("{\"success\":false,\"message\":\"账号不存在\",\"status\":500}");
} else if ("MoreUsersException".equals(message) || res.equals("MoreUsersException")) {
out.println("{\"success\":false,\"message\":\"多个用户名,请联系重置\",\"status\":500}");
} else if ("IncorrectCaptchaException".equals(message)) {
out.println("{\"success\":false,\"message\":\"验证码不正确\",\"status\":500}");
} else {
out.println("{\"success\":false,\"message\":\"未知错误\",\"status\":500}");
}
out.flush();
out.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return false;
}
/**
* 所有请求都会经过的方法。
*/
@Override
protected boolean onAccessDenied(ServletRequest request,
ServletResponse response) throws Exception {
if (isLoginRequest(request, response)) {
if (isLoginSubmission(request, response)) {
if (log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
}
//调用认证
return executeLogin(request, response);
} else {
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
// allow them to see the login page ;)
return true;
}
} else {
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the "
+ "Authentication url [" + getLoginUrl() + "]");
}
if (!isAjaxRequest((HttpServletRequest) request)) {// 不是ajax请求
saveRequestAndRedirectToLogin(request, response);
} else {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
HttpServletResponse r = (HttpServletResponse) response;
r.setStatus(HttpStatus.OK.value());
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.println("{\"success\":false,\"message\":\"login\",\"status\":401}");
out.flush();
out.close();
}
return false;
}
}
private boolean isAjaxRequest(HttpServletRequest request) {
return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With"));
}
}