http从定向到https后post请求被强制转换为get请求

本公司使用耶鲁大学的cas做单点登录服务器,在org.jasig.cas.client.authentication.AuthenticationFilter(过滤拦截请求,进行身份验证)中在181行this.authenticationRedirectStrategy.redirect(request, response, urlToRedirectTo);出现的问题

在tomcat的web.xml中配置

<login-config>  
    <!-- Authorization setting for SSL -->  
    <auth-method>CLIENT-CERT</auth-method>  
    <realm-name>Client Cert Users-only Area</realm-name>  
</login-config>  
<security-constraint>  
    <!-- Authorization setting for SSL -->  
    <web-resource-collection >  
        <web-resource-name >SSL</web-resource-name>  
        <url-pattern>/*</url-pattern>  
    </web-resource-collection>  
    <user-data-constraint>  
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>  
    </user-data-constraint>  
</security-constraint>

http get 请求 都能被重定向到https get 上,但是 http post 请求不行,后台老是报requestMethod GET not supported,访问的post 方法变成了get

在网上看到了一篇博客,nginx中遇到此问题是如何解决的

server {
listen 80;
server_name *.snsprj.cn;
return 307 https://hostrequest_uri;

}

然而我的请求状态码为302

查询相关资料,摘自wikipedia

302 Found

要求客户端执行临时重定向(原始描述短语为“Moved Temporarily”)。[20]由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
新的临时性的URI应当在响应的Location域中返回。除非这是一个HEAD请求,否则响应的实体中应当包含指向新的URI的超链接及简短说明。
如果这不是一个GET或者HEAD请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。

注意:虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将302响应视作为303响应,并且使用GET方式访问在Location中规定的URI,而无视原先请求的方法。因此状态码303和307被添加了进来,用以明确服务器期待客户端进行何种反应。


307 Temporary Redirect

在这种情况下,请求应该与另一个URI重复,但后续的请求应仍使用原始的URI。 与302相反,当重新发出原始请求时,不允许更改请求方法。 例如,应该使用另一个POST请求来重复POST请求


解决办法

由于我使用的是tomcat 进行重定向的,从上文中也可以看出tomcat 默认进行的是302重定向,不符合我们的需求,那又什么办法可以解决呢?办法就是不用tomcat提供的配置,那就是我们自己后台程序处理,毕竟用人家的受限制,自己搞,想怎么弄就怎么弄。自己做的话很明显需要一个过滤器,在请求到达sevlet 之前进行处理,代码如下:

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
@WebFilter(urlPatterns="/*",filterName="HttpsFilter")
/**
 *  过滤器,将http 请求转发到https请求上来
 *  重定向类型:307
 * @author FrankYuan
 *
 */
public class HttpsFilter implements Filter{
    private Logger logger = LoggerFactory.getLogger(HttpsFilter.class);
    private static final String HTTPS ="https";
    private static final int HTTPS_PORT = 8443;
    @Override
    public void destroy() {
        logger.info("------------destroy HttpsFilter --------------");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
         URL newUrl = null;
         if(request.getScheme().equals(HTTPS)) {
             chain.doFilter(request, response);
         }else {
             HttpServletRequest httpRequest = (HttpServletRequest)request;
             HttpServletResponse httpResponse = (HttpServletResponse)response;
             String queryString = httpRequest.getQueryString()==null ? "":"?"+httpRequest.getQueryString();
             httpResponse.setStatus(307);
             String requestUrl = httpRequest.getRequestURL().toString();
             URL reqUrl = new URL(requestUrl+queryString);
             logger.info("【original request-】 "+reqUrl.toString());
             newUrl = new URL(HTTPS,reqUrl.getHost(),HTTPS_PORT,reqUrl.getFile());
             //进行重定向
             logger.info("【new request-】 "+newUrl.toString());
             httpResponse.setHeader("Location", newUrl.toString());
             httpResponse.setHeader("Connection", "close");
             //允许所有跨域请求
             httpResponse.addHeader("Access-Control-Allow-Origin", "*");     
         }

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        logger.info("------------init HttpsFilter --------------");

    }

}
注意:这里又个坑,就是重定向后需要也需要解决跨域问题,不然页面ajax请求 http 地址会出现跨域问题。




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值