前端發起ajax請求,請求首先被跨域Filter過濾,加上Access-Control-Allow-Origin , 而後再被CASFilter過濾,此時沒有登陸的用戶會被重定向到cas.host.cn/login進行登陸,最最最關鍵的地方就在這裏。前端
一般是這樣的:前端發起HttpRequest,後端接受請求並執行res.sendRedirect(),前端接受相應併發起HttpRequest,請求重定向後的頁面,其中HttpRequest不存在跨域問題。
可是如今是這樣的:前端發起XMLHttpRequest, 後端接受請求並執行res.sendRedirect(),前端接受相應併發起XMLHttpRequest,請求重定向後的頁面,可是,因爲cas.host.cn/login沒有配置跨域(安全上也不容許),因此產生了跨域!ajax
思路就是把XMLHttpRequest替換爲HttpRequestjson
方案:後端
@Path("admin/auth") public class AuthController { private static Properties prop = new Properties(); static { InputStream in = CORSFilter.class.getClassLoader().getResourceAsStream("dev.properties"); try { prop.load(in); } catch (IOException e) { e.printStackTrace(); } } @Get("validate") public String validate(Invocation inv) throws JSONException { HttpServletRequest request = inv.getRequest(); Assertion assertion = (Assertion) request.getSession().getAttribute("_const_cas_assertion_"); JSONObject result = new JSONObject(); if (assertion == null || assertion.getPrincipal().getName() == null) { result.put("success",false); result.put("data", prop.getProperty("cas.server.url") + "/login?service=" + prop.getProperty("server.url") + "/thoth-admin/admin/auth/redirect"); } else { result.put("success", true); } return "@json:" + result.toString(); } @Get("redirect") public void redirect(Invocation inv) throws IOException { inv.getResponse().sendRedirect(prop.getProperty("server.url")+"/thoth-admin/admin"); } }
用戶每次發起ajax請求以前,先請求validate接口,檢驗當前用戶的cookie是否失效,若是沒有,就返回{success: true},前端則繼續發送接下來的ajax請求。跨域
若是失效了,就返回一個字符串,內容是將要跳轉的cas驗證地址,前端則手動經過location.href = "這個地址"來進行HttpRequest。cas登陸成功後,會再次重定向,重定向的地址是service=後面的地址。瀏覽器
另外,須要注意的一點是跨域Filter優先級必需要高於CASFIlter,不然請求會先被CASFilter過濾,沒有登陸過得用戶會被302跳轉到cas.mioffice.cn/login, 可是事實是你連跳轉的機會都沒有就會被瀏覽器告知你跨域了。
由於你的請求尚未被跨域Filter過濾,此時響應頭裏尚未Access-Control-Allow-Origin。安全