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
- CAS客户端使用Ajax登陆(即保留原有客户端登录页面)
- 改造CAS单点登录 --- 自定义登陆页面(客户端)
- 让CAS支持客户端自定义登陆页面
- 让CAS支持客户端自定义登陆页面
- CAS 客户端登录验证
- CAS 制作单点登录登录后跳转客户端页面出错
- CAS之客户端使用——基于CAS的单点登陆的研究(下)
- CAS之客户端使用——基于CAS的单点登陆的研究(下)
- 单点登录CAS使用记(二):部署CAS服务器以及客户端
- CAS单点登录-客户端集成(cas-client)(九)
- 让CAS支持客户端自定义登陆页面——客户端篇
- CAS python 客户端登录分析
- Cas单点登录客户端配置
- 单点登录CAS使用记(七):关于服务器超时以及客户端超时的分析
- 单点登录CAS使用记(七):关于服务器超时以及客户端超时的分析
- 改造CAS单点登录 --- 自定义登陆页面(服务端)
- CAS 客户端自定义用户登陆界面
- JASIG-CAS单点登陆服务端客户端配置
- iLnkView隐私政策
- linux用户管理
- rpath和runpath的区别
- Magento获取商品CategoryIds
- ArrayList源码分析
- CAS客户端使用Ajax登陆(即保留原有客户端登录页面)
- 单精度实型和双精度实型的有效位数
- (linux下windows下一样)mysql如何插入中文,解决插入中文报错,ERROR 1366 (HY000):Incorrect string value
- Kmeans算法
- 基于Django的微信公众号开发(3) -- 通过微信公众号开发者认证
- SSM框架-MyBatis篇
- 51nod 1205 流水线调度 贪心(写排序函数)Johnson算法
- 关于 java.lang.IllegalStateException: Fragment already added 解决方式
- Mac:jenkins忘记管理员账号登录密码如何修改管理员账号