加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

CAS环境下的AJAX跨域

发布时间:2020-12-15 21:38:45 所属栏目:百科 来源:网络整理
导读:情况说明: 在单点登录的环境下,所有的文件上传都是通过webuploader上传到文件管理服务器。而webuploader的上传可以参考ajax的请求,相当于是跨域操作。 首先,跨域请求访问的问题,可以通过在文件服务器增加拦截器,修改请求头来解决。 packagecom.util;imp

情况说明:

在单点登录的环境下,所有的文件上传都是通过webuploader上传到文件管理服务器。而webuploader的上传可以参考ajax的请求,相当于是跨域操作。

首先,跨域请求访问的问题,可以通过在文件服务器增加拦截器,修改请求头来解决。

packagecom.util;

importjava.io.IOException;

importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.http.HttpServletResponse;

publicclassSimpleCORSFilterimplementsFilter{

publicvoiddoFilter(ServletRequestreq,ServletResponseres,FilterChainchain)throwsIOException,ServletException{
HttpServletResponseresponse=(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);
}

publicvoidinit(FilterConfigfilterConfig){
}

publicvoiddestroy(){
}

}

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

查阅众多资料,最后在看到org.jasig.cas.client.authentication.AuthenticationFilter才豁然开朗。

/**
*LicensedtoJasigunderoneormorecontributorlicense
*agreements.SeetheNOTICEfiledistributedwiththiswork
*foradditionalinformationregardingcopyrightownership.
*JasiglicensesthisfiletoyouundertheApacheLicense,*Version2.0(the"License");youmaynotusethisfile
*exceptincompliancewiththeLicense.Youmayobtaina
*copyoftheLicenseat:
*
*http://www.apache.org/licenses/LICENSE-2.0
*
*Unlessrequiredbyapplicablelaworagreedtoinwriting,*softwaredistributedundertheLicenseisdistributedon
*an"ASIS"BASIS,WITHOUTWARRANTIESORCONDITIONSOFANY
*KIND,eitherexpressorimplied.SeetheLicenseforthe
*specificlanguagegoverningpermissionsandlimitations
*undertheLicense.
*/

packageorg.jasig.cas.client.authentication;

importorg.jasig.cas.client.util.AbstractCasFilter;
importorg.jasig.cas.client.util.CommonUtils;
importorg.jasig.cas.client.validation.Assertion;

importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjavax.servlet.http.HttpSession;
importjava.io.IOException;

/**
*Filterimplementationtointerceptallrequestsandattempttoauthenticate
*theuserbyredirectingthemtoCAS(unlesstheuserhasaticket).
*<p>
*Thisfilterallowsyoutospecifythefollowingparameters(ateitherthecontext-levelorthefilter-level):
*<ul>
*<li><code>casServerLoginUrl</code>-theurltologintoCAS,i.e.https://cas.rutgers.edu/login</li>
*<li><code>renew</code>-true/falSEOnwhethertouserenewornot.</li>
*<li><code>gateway</code>-true/falSEOnwhethertousegatewayornot.</li>
*</ul>
*
*<p>PleaseseeAbstractCasFilterforadditionalproperties.</p>
*
*@authorScottBattaglia
*@version$Revision:11768$$Date:2007-02-0715:44:16-0500(Wed,07Feb2007)$
*@since3.0
*/
publicclassAuthenticationFilterextendsAbstractCasFilter{

/**
*TheURLtotheCASServerlogin.
*/
privateStringcasServerLoginUrl;

/**
*Whethertosendtherenewrequestornot.
*/
privatebooleanrenew=false;

/**
*Whethertosendthegatewayrequestornot.
*/
privatebooleangateway=false;

privateGatewayResolvergatewayStorage=newDefaultGatewayResolverImpl();

protectedvoidinitInternal(finalFilterConfigfilterConfig)throwsServletException{
if(!isIgnoreInitConfiguration()){
super.initInternal(filterConfig);
setCasServerLoginUrl(getPropertyFromInitParams(filterConfig,"casServerLoginUrl",null));
log.trace("LoadedCasServerLoginUrlparameter:"+this.casServerLoginUrl);
setRenew(parseBoolean(getPropertyFromInitParams(filterConfig,"renew","false")));
log.trace("Loadedrenewparameter:"+this.renew);
setGateway(parseBoolean(getPropertyFromInitParams(filterConfig,"gateway","false")));
log.trace("Loadedgatewayparameter:"+this.gateway);

finalStringgatewayStorageClass=getPropertyFromInitParams(filterConfig,"gatewayStorageClass",null);

if(gatewayStorageClass!=null){
try{
this.gatewayStorage=(GatewayResolver)Class.forName(gatewayStorageClass).newInstance();
}catch(finalExceptione){
log.error(e,e);
thrownewServletException(e);
}
}
}
}

publicvoidinit(){
super.init();
CommonUtils.assertNotNull(this.casServerLoginUrl,"casServerLoginUrlcannotbenull.");
}

publicfinalvoiddoFilter(finalServletRequestservletRequest,finalServletResponseservletResponse,finalFilterChainfilterChain)throwsIOException,ServletException{
finalHttpServletRequestrequest=(HttpServletRequest)servletRequest;
finalHttpServletResponseresponse=(HttpServletResponse)servletResponse;
finalHttpSessionsession=request.getSession(false);
finalAssertionassertion=session!=null?(Assertion)session.getAttribute(CONST_CAS_ASSERTION):null;

if(assertion!=null){
filterChain.doFilter(request,response);
return;
}

finalStringserviceUrl=constructServiceUrl(request,response);
finalStringticket=CommonUtils.safeGetParameter(request,getArtifactParameterName());
finalbooleanwasGatewayed=this.gatewayStorage.hasGatewayedAlready(request,serviceUrl);

if(CommonUtils.isNotBlank(ticket)||wasGatewayed){
filterChain.doFilter(request,response);
return;
}

finalStringmodifiedServiceUrl;

log.debug("noticketandnoassertionfound");
if(this.gateway){
log.debug("settinggatewayattributeinsession");
modifiedServiceUrl=this.gatewayStorage.storeGatewayInformation(request,serviceUrl);
}else{
modifiedServiceUrl=serviceUrl;
}

if(log.isDebugEnabled()){
log.debug("Constructedserviceurl:"+modifiedServiceUrl);
}

finalStringurlToRedirectTo=CommonUtils.constructRedirectUrl(this.casServerLoginUrl,getServiceParameterName(),modifiedServiceUrl,this.renew,this.gateway);

if(log.isDebugEnabled()){
log.debug("redirectingto""+urlToRedirectTo+""");
}

response.sendRedirect(urlToRedirectTo);
}

publicfinalvoidsetRenew(finalbooleanrenew){
this.renew=renew;
}

publicfinalvoidsetGateway(finalbooleangateway){
this.gateway=gateway;
}

publicfinalvoidsetCasServerLoginUrl(finalStringcasServerLoginUrl){
this.casServerLoginUrl=casServerLoginUrl;
}

publicfinalvoidsetGatewayStorage(finalGatewayResolvergatewayStorage){
	this.gatewayStorage=gatewayStorage;
}
}

看到104行可知,每次的请求都会判断session是否存在,如果session存在,则会继续接下来的请求,否则重定向到CAS服务端。既然如此,则可以在每次的ajax请求中带上;jsessionid=********;这样,就可以每次的请求都能获取到session。

那么问题来了,如何在每次的请求提交前,在url上获取文件上传服务器的sessionid的cookie呢?在这里我采用的是jsonp,在每次上传组件初始化之前,采用jsonp发送初始化请求,获取文件服务器上的sessionid,返回后绑定到请求的url地址后。经测试,问题解决。

@Controller
publicclassInitController{

@RequestMapping("init")
@ResponseBody
publicStringgetId(HttpServletRequestreq,HttpServletResponseres){
HttpSessionsession=req.getSession();
res.setContentType("text/plain");
StringcallbackFunName=req.getParameter("callbackparam");//得到js函数名称
Stringjsonp="";
if(session!=null){
Stringid=session.getId();
jsonp="([{jid:""+id+""}])";
}
returncallbackFunName+jsonp;
}
}
/*初始化上传信息*/
functioninitConfig(){
	$.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
	});
}
functionsuccess_jsonpCallback(obj){
	if(obj.length>0&&obj[0].jid){
		varid=obj[0].jid;
		jid=';jsessionid='+id;
	}else{
		alert("上传信息初始化失败!");
	}
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读