您的位置:首页 > Web前端 > JavaScript

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

2017-11-13 19:14 645 查看

前言

    因为对项目的不熟悉,在使用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、修改客户端

  [b]2.1、修改客户端登录页面表单[/b]

    添加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>


  [b]2.2、利用JSONP获取lt及execution参数[/b]

    添加如下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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐