package com.landtool.lanbase.common.shiro;
|
|
import java.io.IOException;
|
import java.net.URLEncoder;
|
|
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletResponse;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
|
import org.apache.http.HttpStatus;
|
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.authc.AuthenticationException;
|
import org.apache.shiro.authc.AuthenticationToken;
|
import org.apache.shiro.session.Session;
|
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.util.StringUtils;
|
import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
|
import com.google.gson.Gson;
|
import com.landtool.lanbase.common.utils.HttpUtils;
|
import com.landtool.lanbase.common.utils.Result;
|
|
/**
|
* @author lanbase
|
* @Description: TODO(shiro 认证过滤器)
|
* @date 2017-6-23 15:07
|
*/
|
public class ShiroAuthenticatingFilter extends AuthenticatingFilter {
|
|
private static String loginUrl; // http://127.0.0.1:8082/login
|
private static String CasHost;// https://cas.nmsmp.com/cas/
|
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
|
public ShiroAuthenticatingFilter(String loginUrl,String casHost)
|
{
|
this.loginUrl=loginUrl;
|
this.CasHost=casHost;
|
}
|
|
// 创建shiro认证的token
|
@Override
|
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
|
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
String username = httpRequest.getRemoteUser();
|
// 获取请求token
|
String token = getRequestToken((HttpServletRequest) request);
|
ShiroToken shiroToken = null;
|
// if (!StringUtils.isBlank(token)) {
|
// shiroToken = new ShiroToken(token);
|
// } else if (!StringUtils.isBlank(username)) {
|
// shiroToken = new ShiroToken(username, true);
|
// } else {
|
// return null;
|
// }
|
return shiroToken;
|
}
|
|
// protected boolean preHandle(ServletRequest request, ServletResponse
|
// response) throws Exception {
|
// HttpServletRequest httpRequest = WebUtils.toHttp(request);
|
// HttpServletResponse httpResponse = WebUtils.toHttp(response);
|
// if (httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
|
// httpResponse.setHeader("Access-control-Allow-Origin", origin);
|
// httpResponse.setHeader("Access-Control-Allow-Methods",
|
// httpRequest.getMethod());
|
// httpResponse.setHeader("Access-Control-Allow-Headers",
|
// httpRequest.getHeader("Access-Control-Request-Headers"));
|
// httpResponse.setStatus(HttpStatus.OK.value());
|
// return false;
|
// }
|
// return super.preHandle(request, response);
|
// }
|
|
// 是否允许访问
|
@Override
|
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
|
return false;
|
}
|
|
// 拒绝访问的出来
|
@Override
|
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
|
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
// 处理CORS的options请求 by Tanbin
|
if (httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
|
String origin = httpRequest.getHeader("Origin");
|
httpResponse.setHeader("Access-control-Allow-Origin", origin);
|
httpResponse.setHeader("Access-Control-Allow-Methods", httpRequest.getMethod());
|
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
|
httpResponse.setHeader("Access-Control-Allow-Headers",
|
httpRequest.getHeader("Access-Control-Request-Headers"));
|
httpResponse.setStatus(HttpStatus.SC_OK);
|
return false;
|
}
|
|
|
String username = httpRequest.getRemoteUser();
|
if (StringUtils.hasText(username)) {// 已经登录shiro
|
logger.debug("0----已经登录shiro:" + username);
|
return true ;
|
} else {
|
username = getLoginNamefromXml(httpRequest);
|
if (StringUtils.hasText(username)) {
|
Subject subject = SecurityUtils.getSubject();
|
ShiroToken shiroToken = new ShiroToken(username, true);
|
if(!subject.isAuthenticated())
|
{
|
subject.login(shiroToken);
|
logger.debug("8----loginshiro:" );
|
}
|
|
String redirectUrl= getValidateTicketServer(httpRequest);
|
|
logger.debug("3----RedirectOldurl:" + redirectUrl);
|
//WebUtils.issueRedirect(request, response, oldUrl);
|
httpResponse.setHeader("P3P", "CP=CAO PSA OUR");
|
httpResponse.sendRedirect(redirectUrl);
|
|
} else {
|
String reloginUrl= getFirstServer(httpRequest);
|
reloginUrl= CasHost + "login?service="+URLEncoder.encode( reloginUrl);
|
logger.debug("1----RedirectCasloginUrl:" + reloginUrl);
|
httpResponse.sendRedirect(reloginUrl);// 用户名不存在跳转回登录页面
|
return false;
|
}
|
}
|
return true ;
|
}
|
|
@Override
|
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request,
|
ServletResponse response) {
|
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
httpResponse.setContentType("application/json;charset=utf-8");
|
try {
|
// 处理登录失败的异常
|
Throwable throwable = e.getCause() == null ? e : e.getCause();
|
Result r = Result.error(HttpStatus.SC_UNAUTHORIZED, throwable.getMessage());
|
|
String json = new Gson().toJson(r);
|
httpResponse.getWriter().print(json);
|
} catch (IOException e1) {
|
|
}
|
|
return false;
|
}
|
|
/**
|
* 获取请求的token
|
*/
|
private String getRequestToken(HttpServletRequest httpRequest) {
|
// 从header中获取token
|
String token = httpRequest.getHeader("token");
|
|
// 如果header中不存在token,则从参数中获取token
|
if (!StringUtils.hasText(token)) {
|
token = httpRequest.getParameter("token");
|
}
|
|
return token;
|
}
|
|
|
|
private String getLoginNamefromXml(HttpServletRequest request) throws Exception {
|
String username = "";
|
|
Subject subject = SecurityUtils.getSubject();
|
Session session =subject.getSession(true);
|
username = session.getAttribute("shirousername") == null ? ""
|
: session.getAttribute("shirousername").toString();
|
logger.debug("4----shirousername:" + session.getAttribute("shirousername") +(session.getId() ));
|
if (org.springframework.util.StringUtils.isEmpty(username)) {
|
|
|
String ticket = request.getParameter("ticket");
|
|
if (!org.springframework.util.StringUtils.isEmpty(ticket)) {
|
|
String reloginUrl= getValidateTicketServer(request);
|
|
String url = CasHost.replace("https", "http");
|
String validateurl = url + "serviceValidate?ticket=" + ticket + "&service=" + URLEncoder.encode(reloginUrl);
|
|
logger.debug("2----ServiceValidate:" + validateurl);
|
|
String casxml;
|
casxml = HttpUtils.get(validateurl);
|
logger.debug(casxml);
|
Integer index = casxml.indexOf("<cas:user>");
|
Integer end = casxml.indexOf("</cas:user>");
|
|
if (index > 0) {
|
username = casxml.substring(index + 10, end);
|
}
|
}
|
}
|
return username;
|
}
|
|
private String getValidateTicketServer(HttpServletRequest request) {
|
String server = getServerParameter(request);
|
|
String reloginUrl= request.getRequestURL().toString();
|
if(StringUtils.hasText( server))
|
{
|
reloginUrl+="?"+server;
|
}
|
return reloginUrl;
|
}
|
|
|
private String getServerParameter(HttpServletRequest request) {
|
String server = request.getQueryString();
|
String ticket = request.getParameter("ticket");
|
if (!org.springframework.util.StringUtils.isEmpty(ticket)) {
|
server = server.replace("ticket=" + ticket, "");
|
if (server.endsWith("&"))
|
server = server.substring(0, server.length() - 1);
|
}
|
return server;
|
}
|
|
|
/***
|
* 获取原始访问路径
|
*
|
* @return
|
*/
|
private String getFirstServer(HttpServletRequest httpRequest) {
|
String reloginUrl= httpRequest.getRequestURL().toString();
|
if(StringUtils.hasText( httpRequest.getQueryString()))
|
{
|
reloginUrl+="?"+httpRequest.getQueryString();
|
}
|
return reloginUrl;
|
}
|
|
}
|