CAS环境下的AJAX跨域

前端之家收集整理的这篇文章主要介绍了CAS环境下的AJAX跨域前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

情况说明:

在单点登录的环境下,所有的文件上传都是通过webuploader上传文件管理服务器。而webuploader的上传可以参考ajax的请求,相当于是跨域操作。
首先,跨域请求访问的问题,可以通过在文件服务器增加拦截器,修改请求头来解决
package com.sdzn.util;
import java.io.IOException;
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.http.HttpServletResponse;
public class SimpleCORSFilter implements Filter {
    public void doFilter(ServletRequest req,ServletResponse res,FilterChain chain) throws IOException,ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin","*");
        response.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE");
        response.setHeader("Access-Control-Max-Age","3600");
        response.setHeader("Access-Control-Allow-Headers","x-requested-with");
        chain.doFilter(req,res);
    }
    public void init(FilterConfig filterConfig) {
    }
    public void destroy() {
    }
}


而在CAS的环境下,跨域的请求还会面临登录验证的重定向 ,但是ajax是不支持重定向的,进而导致文件上传的不成功。

查阅众多资料,最后在看到 org.jasig.cas.client.authentication.AuthenticationFilter 才豁然开朗。
  1. /**
     * Licensed to Jasig under one or more contributor license
     * agreements. See the NOTICE file distributed with this work
     * for additional information regarding copyright ownership.
     * Jasig licenses this file to you under the Apache License,* Version 2.0 (the "License"); you may not use this file
     * except in compliance with the License. You may obtain a
     * copy of the License at:
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing,* software distributed under the License is distributed on
     * an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND,either express or implied. See the License for the
     * specific language governing permissions and limitations
     * under the License.
     */
    package org.jasig.cas.client.authentication;
    import org.jasig.cas.client.util.AbstractCasFilter;
    import org.jasig.cas.client.util.CommonUtils;
    import org.jasig.cas.client.validation.Assertion;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    /**
     * Filter implementation to intercept all requests and attempt to authenticate
     * the user by redirecting them to CAS (unless the user has a ticket).
     * <p>
     * This filter allows you to specify the following parameters (at either the context-level or the filter-level):
     * <ul>
     * <li><code>casServerLoginUrl</code> - the url to log into CAS,i.e. https://cas.rutgers.edu/login</li>
     * <li><code>renew</code> - true/false on whether to use renew or not.</li>
     * <li><code>gateway</code> - true/false on whether to use gateway or not.</li>
     * </ul>
     *
     * <p>Please see AbstractCasFilter for additional properties.</p>
     *
     * @author Scott Battaglia
     * @version $Revision: 11768 $ $Date: 2007-02-07 15:44:16 -0500 (Wed,07 Feb 2007) $
     * @since 3.0
     */
    public class AuthenticationFilter extends AbstractCasFilter {
        /**
         * The URL to the CAS Server login.
         */
        private String casServerLoginUrl;
        /**
         * Whether to send the renew request or not.
         */
        private boolean renew = false;
        /**
         * Whether to send the gateway request or not.
         */
        private boolean gateway = false;
        
        private GatewayResolver gatewayStorage = new DefaultGatewayResolverImpl();
        protected void initInternal(final FilterConfig filterConfig) throws ServletException {
            if (!isIgnoreInitConfiguration()) {
                super.initInternal(filterConfig);
                setCasServerLoginUrl(getPropertyFromInitParams(filterConfig,"casServerLoginUrl",null));
                log.trace("Loaded CasServerLoginUrl parameter: " + this.casServerLoginUrl);
                setRenew(parseBoolean(getPropertyFromInitParams(filterConfig,"renew","false")));
                log.trace("Loaded renew parameter: " + this.renew);
                setGateway(parseBoolean(getPropertyFromInitParams(filterConfig,"gateway","false")));
                log.trace("Loaded gateway parameter: " + this.gateway);
                final String gatewayStorageClass = getPropertyFromInitParams(filterConfig,"gatewayStorageClass",null);
                if (gatewayStorageClass != null) {
                    try {
                        this.gatewayStorage = (GatewayResolver) Class.forName(gatewayStorageClass).newInstance();
                    } catch (final Exception e) {
                        log.error(e,e);
                        throw new ServletException(e);
                    }
                }
            }
        }
        public void init() {
            super.init();
            CommonUtils.assertNotNull(this.casServerLoginUrl,"casServerLoginUrl cannot be null.");
        }
        public final void doFilter(final ServletRequest servletRequest,final ServletResponse servletResponse,final FilterChain filterChain) throws IOException,ServletException {
            final HttpServletRequest request = (HttpServletRequest) servletRequest;
            final HttpServletResponse response = (HttpServletResponse) servletResponse;
            final HttpSession session = request.getSession(false);
            final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
            if (assertion != null) {
                filterChain.doFilter(request,response);
                return;
            }
            final String serviceUrl = constructServiceUrl(request,response);
            final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());
            final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request,serviceUrl);
            if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
                filterChain.doFilter(request,response);
                return;
            }
            final String modifiedServiceUrl;
            log.debug("no ticket and no assertion found");
            if (this.gateway) {
                log.debug("setting gateway attribute in session");
                modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request,serviceUrl);
            } else {
                modifiedServiceUrl = serviceUrl;
            }
            if (log.isDebugEnabled()) {
                log.debug("Constructed service url: " + modifiedServiceUrl);
            }
            final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl,getServiceParameterName(),modifiedServiceUrl,this.renew,this.gateway);
            if (log.isDebugEnabled()) {
                log.debug("redirecting to \"" + urlToRedirectTo + "\"");
            }
            response.sendRedirect(urlToRedirectTo);
        }
        public final void setRenew(final boolean renew) {
            this.renew = renew;
        }
        public final void setGateway(final boolean gateway) {
            this.gateway = gateway;
        }
        public final void setCasServerLoginUrl(final String casServerLoginUrl) {
            this.casServerLoginUrl = casServerLoginUrl;
        }
        
        public final void setGatewayStorage(final GatewayResolver gatewayStorage) {
        	this.gatewayStorage = gatewayStorage;
        }
    }


看到104行可知,每次的请求都会判断session是否存在,如果session存在,则会继续接下来的请求,否则重定向到CAS服务端。既然如此,则可以在每次的ajax请求中带上;jsessionid=********;这样,就可以每次的请求都能获取到session。
那么问题来了,如何在每次的请求提交前,在url上获取文件上传服务器的sessionid的cookie呢?在这里我采用的是jsonp,在每次上传组件初始化之前,采用jsonp发送初始化请求,获取文件服务器上的sessionid,返回后绑定到请求的URL地址后。经测试,问题解决
  1. @Controller
    public class InitController {
        @RequestMapping("init")
        @ResponseBody
        public String getId(HttpServletRequest req,HttpServletResponse res) {
            HttpSession session = req.getSession();
            res.setContentType("text/plain");
            String callbackFunName = req.getParameter("callbackparam");// 得到js函数名称
            String jsonp = "";
            if (session != null) {
                String id = session.getId();
                jsonp = "([ { jid:\"" + id + "\"}])";
            }
            return callbackFunName + jsonp;
        }
    }
    /* 初始化上传信息 */
    function initConfig() {
    	$.ajax({  
    		url:prefix+'/init',data:'',async:false,dataType: "jsonp",jsonp: "callbackparam",//服务端用于接收callback调用的function名的参数   
    		jsonpCallback: "success_jsonpCallback",//callback的function名称,服务端会把名称和data一起传递回来 
    		success:function(result) {
    			uploaderInit();
    		},error:function(){
    			alert("上传信息初始化失败!");
    		},timeout:3000  
    	}); 
    }
    function success_jsonpCallback(obj){
    	if(obj.length>0&&obj[0].jid){
    		var id = obj[0].jid;
    		jid=';jsessionid='+id;
    	}else{
    		alert("上传信息初始化失败!");
    	}
    }


原文链接:https://www.f2er.com/ajax/162856.html

猜你在找的Ajax相关文章