JwtAuthenticationFilter.java
package com.mycim.webapp.secutiry.shiro.filter;
import com.fa.sesa.exception.ErrorCode;
import com.fa.sesa.i18n.I18nUtils;
import com.mycim.framework.utils.msg.JsonUtils;
import com.mycim.framework.utils.msg.model.Response;
import com.mycim.framework.utils.msg.model.ResponseHeader;
import com.mycim.webapp.secutiry.jwt.JwtUtils;
import com.mycim.webapp.secutiry.jwt.token.JwtToken;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author pinyan.song
*/
public class JwtAuthenticationFilter extends BasicHttpAuthenticationFilter {
@Override
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
req.getSession();
String authorization = JwtUtils.getToken(req);
try {
JwtToken jwtToken = new JwtToken(authorization);
/*
* 提交给Realm 登录,发生异常代表失败,反之代表成功, 成功情况下,续存Token(更换)
*/
getSubject(request, response).login(jwtToken);
JwtUtils.setTokenToCookie(httpServletResponse, JwtUtils.sign(jwtToken));
} catch (Exception e) {
// 如果发生异常, 清空token
JwtUtils.setTokenToCookie(httpServletResponse, null);
//直接返回false,交给 onAccessDenied 处理
return false;
}
return true;
}
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
return isLoginAttempt(request, response);
}
private boolean tokenIsNull(ServletRequest request) {
HttpServletRequest req = (HttpServletRequest) request;
return JwtUtils.getToken(req) != null;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
//false by default or we wouldn't be in this method
boolean loggedIn = false;
if (!isLoginAttempt(request, response) && tokenIsNull(request)) {
loggedIn = executeLogin(request, response);
}
if (!loggedIn) {
sendChallenge(request, response);
}
if(loggedIn){
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if(httpServletRequest.getRequestURI().endsWith("/changepasswordedit.do")){//只允许修改提交不重定向
return true;
}
String authorization = JwtUtils.getToken(httpServletRequest);
JwtToken jwtToken = new JwtToken(authorization);
if(jwtToken.isNeedUpdatePwd()){
//跳转修改密码页面
((HttpServletResponse)response).sendRedirect("login.do?action=main");
}
}
return loggedIn;
}
@Override
protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
return pathsMatch(getLoginUrl(), request);
}
@Override
protected boolean sendChallenge(ServletRequest request, ServletResponse response) {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//如果为Ajax
if (req.getHeader("X-Requested-With") != null && "XMLHttpRequest".equals(req.getHeader("X-Requested-With"))) {
httpServletResponse.setStatus(200);
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.setHeader("Cache-Control", "no-cache");
try {
Response res = new Response();
ResponseHeader responseHeader = new ResponseHeader();
responseHeader.setCode(ErrorCode.invalid.getErrCode());
responseHeader.setSubCode("ShiroValidationFailed");
responseHeader.setSubMessage(I18nUtils.getMessage("token.time_out", "Token Time Out"));
res.setHead(responseHeader);
httpServletResponse.getWriter().write(JsonUtils.toString(res));
} catch (IOException e) {
e.printStackTrace();
}
} else {
//正常的struts请求 返回login
try {
redirectToLogin(req, httpServletResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
}