shiro使用apache代理时,自动加上项目名称

有一个项目使用了shiro认证和授权,当该项目使用apache的VirtualHost反向代理时,出现了一个问题,

如下,是apache的配置

<VirtualHost *:80>
	
	ServerName xxx.xxx.cn
	ProxyPass  / http://192.168.1.8:8088/projectName/
	ProxyPassReverse / http://192.168.1.8:8088/projectName/
	ProxyPassReverseCookiePath /projectName /
	
	
</VirtualHost>

当我们输入xxx.xxx.cn 如果使我们没登录过项目,应该是跳转到登录页面也就是xxx.xxx.cn/login 的url

但是现在会自动给我们加上项目名变成了xxx.xxx.cn/projectName/login的url

原因是我们使用了shiro,shiro给我们加上了项目的名称。

解决方法

修改apache的配置加上header

<VirtualHost *:80>
	
	ServerName xxx.xxx.cn
	ProxyPass  / http://192.168.1.8:8088/projectName/
	ProxyPassReverse / http://192.168.1.8:8088/projectName/
	ProxyPassReverseCookiePath /projectName /
	RequestHeader append myHeader "aaabbb"
	
</VirtualHost>

 然后在我们的项目中写一个filter 继承shiro的FormAuthenticationFilter,这个是认证的filter,

然后我们取出header值,如果是我们设置的,则我们就把项目名去掉

package com.qs.catering.admin.filter;

import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;

public class CustomFormAuthenticationFilter  extends FormAuthenticationFilter{

	@Override
	protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
		HttpServletRequest req = (HttpServletRequest) request;
		String loginUrl = getLoginUrl();
		if("aaabbb".equals(req.getHeader("myHeader"))){
//此处的第5个参数,就是把项目名称去掉
			WebUtils.issueRedirect(request, response, loginUrl, null, false, true);
		}else{
			WebUtils.issueRedirect(request, response, loginUrl);
		}
	}

	

}

同样在写一个退出filger,集成 LogoutFilter,和认证的filter同理

package com.qs.catering.admin.filter;

import java.util.Locale;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.util.WebUtils;

public class CustomLogoutFilter extends LogoutFilter {
	private static Logger log = Logger.getLogger(CustomLogoutFilter.class);
	@Override
	protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {

		Subject subject = getSubject(request, response);

        // Check if POST only logout is enabled
        if (isPostOnlyLogout()) {

            // check if the current request's method is a POST, if not redirect
            if (!WebUtils.toHttp(request).getMethod().toUpperCase(Locale.ENGLISH).equals("POST")) {
               return onLogoutRequestNotAPost(request, response);
            }
        }

        String redirectUrl = getRedirectUrl(request, response, subject);
        //try/catch added for SHIRO-298:
        try {
            subject.logout();
        } catch (SessionException ise) {
            log.debug("Encountered session exception during logout.  This can generally safely be ignored.", ise);
        }
        HttpServletRequest req = (HttpServletRequest) request;
        if("aaabbb".equals(req.getHeader("myHeader"))){
        	WebUtils.issueRedirect(request, response, redirectUrl, null, false, true);
        }else{
        	issueRedirect(request, response, redirectUrl);
        }
        return false;
	}

}

我们的shirioconfig 中加入下代码

Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
        // 将自定义的FormAuthenticationFilter注入shiroFilter中
        filters.put("authc", new CustomFormAuthenticationFilter());
        // 将自定义的LogoutFilter注入shiroFilter中
        filters.put("logout", new CustomLogoutFilter());

就是下图中


shiro使用apache代理时,自动加上项目名称
 

这样就解决了我们的问题

相关推荐