CAS客户端使用Ajax登陆(即保留原有客户端登录页面)

来源:互联网 发布:lol老是网络断开连接 编辑:程序博客网 时间:2024/05/16 19:56

前言

    因为对项目的不熟悉,在使用CAS的时候,踩了蛮多的坑,前面的文章提到了怎么跟shiro集成,可以说是花了比较多的时间。而实际的需求却不止于此。公司希望保留原有应用的登录页面。这个可又是一个大坑啊。自己花了几天时间来实现这个需求。逛了不知道多少的帖子。

    综合网上的帖子来看,在保留原有的登陆页面上有两个实现的思路,一个是通过Ajax+JSONP在前端做,另一个是在后端用HttpClient来实现。总体的思路都是模拟请求登陆页,先获取lt及execution再获取Ticket。

    首先用的HttpClient来实现,但是后面发现登陆的问题是解决了,但是存在Cookie跨域的问题,这样子就失去了单点登录的意义了。(虽然错了后面会贴出来Demo)

由于没有找到解决方案,后面采取Ajax+JSONP来实现,这种方式比较简单。虽然保留了客户端应用的界面,但是原有的登陆方法是已经弃用了的。只是保留了界面,原来的CASclient的配置还是要配置。shiro+cas的集成前篇已经说了,所以这里就不再重复贴了。需要的可以找一下前面的帖子。[直达链接]

一、使用Ajax+JSONP实现

1、在server的casLoginView.jsp页面添加如下代码,用来获取lt及execution

<%    String action = request.getParameter("action");    if (action != null && action.equals("getlt")) {        String callbackName = request.getParameter("callback");        String jsonData = "{\"lt\":\"" + request.getAttribute("loginTicket") + "\", \"execution\":\"" + request.getAttribute("flowExecutionKey") + "\"}";        String jsonp = callbackName + "(" + jsonData + ")";        //response.setContentType("application/javascript");        response.getWriter().write(jsonp);    }else{%><!--.....原来页面的HTML代码......--><% } %>

2、修改客户端

  2.1、修改客户端登录页面表单

    添加lt、execution及_eventId表单字段。

    修改表单提交的action为携带service参数的server地址

<form method="post" action="http://www.cas.com/login?service=http://127.0.0.1:8080/cas_client/a/cas" id="loginForm">    <input type="text" id="username" name="username" value="${username}" title="请输入用户名" placeholder="用户名" class="login1form_control login1uname"/>    <input type="password" id="password" name="password" title="请输入密码" placeholder="密码" class="login1form_control login1pword login1m-b"/>    <%--CAS单点登录--%>    <input type="hidden" name="lt" id="lt" value=""/>    <input type="hidden" name="execution" id="execution" value=""/></span>    <input type="hidden" name="_eventId" value="submit"/>    <%--CAS单点登录--%>    <button id="login1btn" class="login1btn login1btn-success login1btn-block" type="submit">登录</button></form>
  2.2、利用JSONP获取lt及execution参数

    添加如下js,用来初始化lt、execution的值

    注意修改server地址及service参数

<script type="text/javascript">    $(function(){        $.getJSON("http://www.cas.com/login?action=getlt&service=http://127.0.0.1:8080/cas_client/a/cas&callback=?",            function (data) {                $("#lt").val(data.lt);                $("#execution").val(data.execution);            })    })</script>

这种方式只需在配置好CAS之后修改页面即可。



二、使用HttpClient来实现

    Demo如下,这种方式仅供参考,未解决跨域问题

import org.apache.http.Header;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpUriRequest;import org.apache.http.client.methods.RequestBuilder;import org.apache.http.cookie.Cookie;import org.apache.http.impl.client.BasicCookieStore;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.URI;import java.util.HashMap;import java.util.List;import java.util.Map;/** * A example that demonstrates how HttpClient APIs can be used to perform * form-based logon. 一个例子,演示了如何HttpClient API可用于执行基于表单的登录。 */public class ClientFormLogin {    private static final String USERNAME = "admin";    private static final String PASSWORD = "123456";    private static final String CAS_LOGIN_URL = "http://www.cas.com/login?service=http://127.0.0.1:8081/cas_client/a/cas";    public static void main(String[] args) throws Exception {        BasicCookieStore cookieStore = new BasicCookieStore();        CloseableHttpClient httpclient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();        try {            //访问Server登陆页面获得Cookie            HttpGet initServerGet = new HttpGet(CAS_LOGIN_URL);            CloseableHttpResponse response1 = httpclient.execute(initServerGet);            try {                HttpEntity entity = response1.getEntity();                System.out.println("Login form get: " + response1.getStatusLine());                EntityUtils.consume(entity);                System.out.println("Initial set of cookies:");                List<Cookie> cookies = cookieStore.getCookies();                if (cookies.isEmpty()) {                    System.out.println("None");                } else {                    for (int i = 0; i < cookies.size(); i++) {                        System.out.println("- " + cookies.get(i).toString());                    }                }            } finally {                response1.close();            }            //获取lt及execution参数            Map<String, String> map = doCasLoginRequest(httpclient, CAS_LOGIN_URL);            //封装参数            HttpUriRequest login = RequestBuilder.post()                    .setUri(new URI(CAS_LOGIN_URL))                    .addParameter("username", USERNAME)                    .addParameter("password", PASSWORD)                    .addParameter("lt", map.get("lt"))                    .addParameter("_eventId", "submit")                    .addParameter("submit", "登录")                    .addParameter("execution", map.get("execution")).build();            CloseableHttpResponse response2 = httpclient.execute(login);            String location = response2.getFirstHeader("Location").getValue();            System.out.println(location.substring(location.indexOf("?ticket=") + 8));            Header[] tgtHead = response2.getHeaders("Set-Cookie");            //无需重新再请求,否则会导致重定向过多            HttpGet httpGet = new HttpGet(location);            httpGet.setHeaders(tgtHead);            CloseableHttpResponse response3 = httpclient.execute(httpGet);            System.out.println("请求访问地址状态码: " + response3.getStatusLine());            String body = EntityUtils.toString(response3.getEntity());            try {                HttpEntity entity = response2.getEntity();                System.out.println("Login form get: " + response2.getStatusLine());                EntityUtils.consume(entity);                System.out.println("Post logon cookies:");                List<Cookie> cookies = cookieStore.getCookies();                if (cookies.isEmpty()) {                    System.out.println("None");                } else {                    for (int i = 0; i < cookies.size(); i++) {                        System.out.println("- " + cookies.get(i).toString());                    }                }            } finally {                response2.close();            }        } finally {            httpclient.close();        }    }    private static Map<String, String> doCasLoginRequest(HttpClient httpclient, String url)            throws IOException {        Map<String, String> result = new HashMap<>(16);        HttpGet httpget = new HttpGet(url);        HttpResponse response = httpclient.execute(httpget);        HttpEntity entity = response.getEntity();        BufferedReader rd = new BufferedReader(new InputStreamReader(                entity.getContent(), "UTF-8"));        String tempLine = rd.readLine();        String lt = "<input type=\"hidden\" name=\"lt\" value=\"";        String execution = "<input type=\"hidden\" name=\"execution\" value=\"";        while (tempLine != null) {            int lt_index = tempLine.indexOf(lt);            if (lt_index != -1) {                String s1 = tempLine.substring(lt_index + lt.length());                int index1 = s1.indexOf("\"");                if (index1 != -1) {                    result.put("lt", s1.substring(0, index1));                }            }            int execution_index = tempLine.indexOf(execution);            if (execution_index != -1) {                String s1 = tempLine.substring(execution_index + execution.length());                int index1 = s1.indexOf("\"");                if (index1 != -1) {                    result.put("execution", s1.substring(0, index1));                }            }            tempLine = rd.readLine();        }        if (entity != null) {            entity.consumeContent();        }        return result;    }}

参考文章:http://blog.csdn.net/just_lion/article/details/39316169

          http://blog.csdn.net/mengtianyalll/article/details/50073099

阅读全文
0 0