先后端分离下的跨域CAS请求

最重要的两点:

  1. ajax请求跨域的时候,默认不会携带cookie。
  2. 请求分为普通请求(HttpRequest)和Ajax请求(XMLHttpRequest)

先屡一下跨域CAS认证的流程:

前端发起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。安全

相关文章
相关标签/搜索