CAS环境下的AJAX跨域

来源:互联网 发布:mac 卸载自带输入法 编辑:程序博客网 时间:2024/06/08 11:51

情况说明:

        在单点登录的环境下,所有的文件上传都是通过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. @Controllerpublic 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("上传信息初始化失败!");}}


点击打开链接
0 0
原创粉丝点击