域名绑在nginx上,又反代了tomcat
又想以域名直接访问web应用
shiro在处理过程中,用了如下代码
public final void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws IOException { StringBuilder targetUrl = new StringBuilder(); if(this.contextRelative && this.getUrl().startsWith("/")) { targetUrl.append(request.getContextPath()); } targetUrl.append(this.getUrl()); this.appendQueryProperties(targetUrl, model, this.encodingScheme); this.sendRedirect(request, response, targetUrl.toString(), this.http10Compatible); }
默认登录拦截contextRelatie=true
导致tomcat每次取出了应用名xxx
但需求是通过域名直接访问应用,且域名不能绑tomcat那台机器,只能绑在nginx上。
nginx反代配置则必须如下(IP:PORT请自定义)
location ^~ / { proxy_pass http://10.10.10.10:8080/xxx/; proxy_set_header Host $host:80; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Via "nginx"; break; }
那么由于shiro上面一段代码,会跳转到
http://www.域名.com/xxx/login.html
实际地址变成了http://10.10.10.10:8080/xxx/xxx/login.html
多了一层xxx
怎么解决这个问题呢,解决方案是重写Filter,以下是我重写的一个Filter,仅供参考
import org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter; import org.apache.shiro.web.util.WebUtils; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; /** * Created by jdkleo on 2017/2/10. */ public class PanyAuthcFilter extends PassThruAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if(this.isLoginRequest(request, response)) { return true; } else { this.saveRequest(request); String via = ((HttpServletRequest)request).getHeader("Via"); if (via != null && "nginx".equals(via.toLowerCase())){//如果是nginx,就不需要contextRelative上下文关系 WebUtils.issueRedirect(request, response, this.getLoginUrl(),null,false); }else { WebUtils.issueRedirect(request, response, this.getLoginUrl()); } return false; } } }