研究kisso跨域登录的心得
kisso OA所有请求都跳转到这个接口,登录只有这一个入口
http://my.web.com:8090/oa/login.ht @RequestMapping("/login.ht")
public String login(HttpServletRequest request,HttpServletResponse response) {
SSOToken token = SSOHelper.getToken(request);
if (token == null) {
//重定向至代理跨域地址页
return response.sendRedirect("http://sso.test.com:8080/login.html?ReturnURL=http%3A%2F%2Fmy.web.com%3A8090%2Fproxylogin.ht");
} else {
//从token中取出信息,进行相关信息初始化。
String userId = token.getUid();
//.......
}
return "index";
} SSO中心
http://sso.test.com:8080/login.html @RequestMapping("/login.ht")
public String login(HttpServletRequest request,HttpServletResponse response) {
String returnUrl = request.getParameter(SSOConfig.getInstance().getParamReturl());//因为XXXXX处记录了,所以此处可以取到。
Token token = SSOHelper.getToken(request);
if (token == null) {
//正常登录 需要过滤sql及脚本注入
WafRequestWrapper wr = new WafRequestWrapper(request);
String name = wr.getParameter("userid");//账号、密码认证
if (name != null && !"".equals(name)) {
//设置登录 Cookie 最后一个参数 true 时添加 cookie 同时销毁当前 JSESSIONID 创建信任的 JSESSIONID
SSOToken st = new SSOToken(request, "");
SSOHelper.setSSOCookie(request, response, st, true);
// 重定向到指定地址 returnUrl
if (StringUtils.isEmpty(returnUrl)) {
returnUrl = "/index.html";
} else {
returnUrl = HttpUtil.decodeURL(returnUrl);
}
return response.sendRedirect(returnUrl);
} else {
if (StringUtils.isNotEmpty(returnUrl)) {
request.setAttribute("ReturnURL", returnUrl);//存储起来XXXXX
}
return "login";
}
} else {
if (StringUtils.isEmpty(returnUrl)) {
returnUrl = "/index.html";
}
return response.sendRedirect(returnUrl);
}
} OA中,经SSO登录后,又重定向回来
http://my.web.com:8090/oa/proxylogin.ht
@RequestMapping("/proxylogin.ht")
public String proxylogin(HttpServletRequest request,HttpServletResponse response) {
// 用户自定义配置获取 由于不确定性,kisso 提倡,用户自己定义配置。
PropertiesUtil prop = SSOConfig.getSSOProperties(); //业务系统私钥签名 authToken 自动设置临时会话 cookie 授权后自动销毁
AuthToken at = SSOHelper.askCiphertext(request, response, prop.get("sso.defined.my_private_key")); //at.getUuid() 作为 key 设置 authToken 至分布式缓存中,然后 sso 系统二次验证 //askurl 询问 sso 是否登录地址
String askurl = prop.get("sso.defined.askurl");
request.setAttribute("askurl", askurl); //askTxt 询问 token 密文
String askData = at.encryptAuthToken();
request.setAttribute("askData", askData); //my 确定是否登录地址
String okurl = prop.get("sso.defined.oklogin");
request.setAttribute("okurl", okurl); return "proxylogin";
} proxylogin.jsp页面中js
$(function(){
$.ajax({
url: askurl,
data: {askData:askData},
success: function(d){
if(d.msg == "-1"){
window.location.href = "http://sso.test.com:8080/login.html?ReturnURL=http%3A%2F%2Fmy.web.com%3A8090%2Fproxylogin.html";
}else{
$.post(okurl, {replyTxt:d.msg} , function(e) {
window.location.href = e.returl;
}, "json");
}
},error:function(){
window.location.href = "http://sso.test.com:8080/login.html?ReturnURL=http%3A%2F%2Fmy.web.com%3A8090%2Fproxylogin.ht"
},
dataType: json
});
}); SSO中askurl地址
http://sso.test.com:8080/replylogin.html
@ResponseBody
@RequestMapping("/replylogin")
public void replylogin(HttpServletRequest request,HttpServletResponse response) {
StringBuffer replyData = new StringBuffer();
replyData.append(request.getParameter("callback")).append("({\"msg\":\"");
Token token = SSOHelper.getToken(request);
if (token != null) {
String askData = request.getParameter("askData");
if (askData != null && !"".equals(askData)) {
//用户自定义配置获取 由于不确定性,kisso 提倡,用户自己定义配置。
PropertiesUtil prop = SSOConfig.getSSOProperties(); //下面开始验证票据,签名新的票据每一步都必须有。
AuthToken at = SSOHelper.replyCiphertext(request, askData);
if (at != null) {
//1、业务系统公钥验证签名合法性(此处要支持多个跨域端,取 authToken 的 app 名找到对应系统公钥验证签名)
at = at.verify(prop.get("sso.defined." + at.getApp() + "_public_key"));
if (at != null) {
//at.getUuid() 作为 key 设置 authToken 至分布式缓存中,然后 sso 系统二次验证
//at.setData(data); 设置自定义信息,当然你也可以直接 at.setData(token.jsonToken()); 把当前 SSOToken 传过去。 at.setUid(token.getUid());//设置绑定用户ID
at.setTime(token.getTime());//设置登录时间 //2、SSO 的私钥签名
at.sign(prop.get("sso.defined.sso_private_key")); //3、生成回复密文票据
replyData.append(at.encryptAuthToken());
} else {
//非法签名, 可以重定向至无权限界面,自己处理
replyData.append("-2");
}
} else {
//非法签名, 可以重定向至无权限界面,自己处理
replyData.append("-2");
}
}
} else {
// 未登录
replyData.append("-1");
}
try {
replyData.append("\"})");
response.setContentType("text/html;charset=" + "UTF-8");
PrintWriter out = response.getWriter();
out.print(replyData);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
} OA中okurl
http://my.web.com:8090/oklogin.ht
@ResponseBody
@RequestMapping("/oklogin")
public void oklogin(HttpServletRequest request,HttpServletResponse response) {
String returl = "http://my.web.com:8090/timeout.html";
//回复密文是否存在 SSO 公钥验证回复密文是否正确 设置 MY 系统自己的 Cookie
String replyTxt = request.getParameter("replyTxt");
if (replyTxt != null && !"".equals(replyTxt)) {
// 用户自定义配置获取 由于不确定性,kisso 提倡,用户自己定义配置。
PropertiesUtil prop = SSOConfig.getSSOProperties();
AuthToken at = SSOHelper.ok(request, response, replyTxt, prop.get("sso.defined.my_public_key"),
prop.get("sso.defined.sso_public_key"));
if (at != null) {
returl = "http://my.web.com:8090/index.html";
SSOToken st = new SSOToken();
st.setUid(at.getUid());
st.setTime(at.getTime()); //设置 true 时添加 cookie 同时销毁当前 JSESSIONID 创建信任的 JSESSIONID
SSOHelper.setSSOCookie(request, response, st, true);
}
}
try {
response.setContentType("text/html;charset=" + "UTF-8");
PrintWriter out = response.getWriter();
out.print("{\"returl\":\"" + returl + "\"}");
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
} 于是整个过程是这样的:
http://my.web.com:8090/oa/login.ht
||
http://sso.test.com:8080/login.html?ReturnURL=http%3A%2F%2Fmy.web.com%3A8090%2Fproxylogin.ht
||
http://my.web.com:8090/oa/proxylogin.ht
||
http://sso.test.com:8080/replylogin.html
||
http://my.web.com:8090/oa/oklogin.ht
||
http://my.web.com:8090/oa/login.ht
http://git.oschina.net/juapk/kisso
kisso
OA所有请求都跳转到这个接口,登录只有这一个入口http://my.web.com:8090/oa/login.ht
@RequestMapping("/login.ht")public String login(HttpServletRequest request,HttpServletResponse response) {SSOToken token = SSOHelper.getToken(request);if (token == null) {//重定向至代理跨域地址页return response.sendRedirect("http://sso.test.com:8080/login.html?ReturnURL=http%3A%2F%2Fmy.web.com%3A8090%2Fproxylogin.ht");} else {//从token中取出信息,进行相关信息初始化。String userId = token.getUid();//.......}return "index";}
SSO中心http://sso.test.com:8080/login.html
@RequestMapping("/login.ht")public String login(HttpServletRequest request,HttpServletResponse response) {String returnUrl = request.getParameter(SSOConfig.getInstance().getParamReturl());//因为XXXXX处记录了,所以此处可以取到。Token token = SSOHelper.getToken(request);if (token == null) {//正常登录 需要过滤sql及脚本注入WafRequestWrapper wr = new WafRequestWrapper(request);String name = wr.getParameter("userid");//账号、密码认证if (name != null && !"".equals(name)) {//设置登录 Cookie 最后一个参数 true 时添加 cookie 同时销毁当前 JSESSIONID 创建信任的 JSESSIONIDSSOToken st = new SSOToken(request, "1000");SSOHelper.setSSOCookie(request, response, st, true);// 重定向到指定地址 returnUrlif (StringUtils.isEmpty(returnUrl)) {returnUrl = "/index.html";} else {returnUrl = HttpUtil.decodeURL(returnUrl);}return response.sendRedirect(returnUrl);} else {if (StringUtils.isNotEmpty(returnUrl)) {request.setAttribute("ReturnURL", returnUrl);//存储起来XXXXX}return "login";}} else {if (StringUtils.isEmpty(returnUrl)) {returnUrl = "/index.html";}return response.sendRedirect(returnUrl);}}
OA中,经V8登录后,又重定向回来http://my.web.com:8090/oa/proxylogin.ht@RequestMapping("/proxylogin.ht")public String proxylogin(HttpServletRequest request,HttpServletResponse response) {// 用户自定义配置获取 由于不确定性,kisso 提倡,用户自己定义配置。PropertiesUtil prop = SSOConfig.getSSOProperties();//业务系统私钥签名 authToken 自动设置临时会话 cookie 授权后自动销毁AuthToken at = SSOHelper.askCiphertext(request, response, prop.get("sso.defined.my_private_key"));//at.getUuid() 作为 key 设置 authToken 至分布式缓存中,然后 sso 系统二次验证//askurl 询问 sso 是否登录地址String askurl = prop.get("sso.defined.askurl");request.setAttribute("askurl", askurl);
//askTxt 询问 token 密文String askData = at.encryptAuthToken();request.setAttribute("askData", askData);
//my 确定是否登录地址String okurl = prop.get("sso.defined.oklogin");request.setAttribute("okurl", okurl);
return "proxylogin";}
proxylogin.jsp页面中js$(function(){$.ajax({url: askurl,data: {askData:askData},success: function(d){if(d.msg == "-1"){ window.location.href = "http://sso.test.com:8080/login.html?ReturnURL=http%3A%2F%2Fmy.web.com%3A8090%2Fproxylogin.html"; }else{$.post(okurl, {replyTxt:d.msg} , function(e) {window.location.href = e.returl;}, "json");}},error:function(){window.location.href = "http://sso.test.com:8080/login.html?ReturnURL=http%3A%2F%2Fmy.web.com%3A8090%2Fproxylogin.ht"},dataType: json });});
V8中askurl地址http://sso.test.com:8080/replylogin.html@ResponseBody@RequestMapping("/replylogin")public void replylogin(HttpServletRequest request,HttpServletResponse response) {StringBuffer replyData = new StringBuffer();replyData.append(request.getParameter("callback")).append("({\"msg\":\"");Token token = SSOHelper.getToken(request);if (token != null) {String askData = request.getParameter("askData");if (askData != null && !"".equals(askData)) {//用户自定义配置获取 由于不确定性,kisso 提倡,用户自己定义配置。PropertiesUtil prop = SSOConfig.getSSOProperties();//下面开始验证票据,签名新的票据每一步都必须有。AuthToken at = SSOHelper.replyCiphertext(request, askData);if (at != null) {//1、业务系统公钥验证签名合法性(此处要支持多个跨域端,取 authToken 的 app 名找到对应系统公钥验证签名)at = at.verify(prop.get("sso.defined." + at.getApp() + "_public_key"));if (at != null) {//at.getUuid() 作为 key 设置 authToken 至分布式缓存中,然后 sso 系统二次验证//at.setData(data); 设置自定义信息,当然你也可以直接 at.setData(token.jsonToken()); 把当前 SSOToken 传过去。at.setUid(token.getUid());//设置绑定用户IDat.setTime(token.getTime());//设置登录时间//2、SSO 的私钥签名at.sign(prop.get("sso.defined.sso_private_key"));//3、生成回复密文票据replyData.append(at.encryptAuthToken());} else {//非法签名, 可以重定向至无权限界面,自己处理replyData.append("-2");}} else {//非法签名, 可以重定向至无权限界面,自己处理replyData.append("-2");}}} else {// 未登录replyData.append("-1");}try {replyData.append("\"})");response.setContentType("text/html;charset=" + "UTF-8");PrintWriter out = response.getWriter();out.print(replyData);out.flush();} catch (IOException e) {e.printStackTrace();}}
OA中okurlhttp://my.web.com:8090/oklogin.ht@ResponseBody@RequestMapping("/oklogin")public void oklogin(HttpServletRequest request,HttpServletResponse response) {String returl = "http://my.web.com:8090/timeout.html";//回复密文是否存在 SSO 公钥验证回复密文是否正确 设置 MY 系统自己的 CookieString replyTxt = request.getParameter("replyTxt");if (replyTxt != null && !"".equals(replyTxt)) {// 用户自定义配置获取 由于不确定性,kisso 提倡,用户自己定义配置。PropertiesUtil prop = SSOConfig.getSSOProperties();AuthToken at = SSOHelper.ok(request, response, replyTxt, prop.get("sso.defined.my_public_key"),prop.get("sso.defined.sso_public_key"));if (at != null) {returl = "http://my.web.com:8090/index.html";SSOToken st = new SSOToken();st.setUid(at.getUid());st.setTime(at.getTime());//设置 true 时添加 cookie 同时销毁当前 JSESSIONID 创建信任的 JSESSIONIDSSOHelper.setSSOCookie(request, response, st, true);}}try { response.setContentType("text/html;charset=" + "UTF-8");PrintWriter out = response.getWriter();out.print("{\"returl\":\"" + returl + "\"}");out.flush();} catch (IOException e) {e.printStackTrace();}}
于是整个过程是这样的:http://my.web.com:8090/oa/login.ht||http://sso.test.com:8080/login.html?ReturnURL=http%3A%2F%2Fmy.web.com%3A8090%2Fproxylogin.ht||http://my.web.com:8090/oa/proxylogin.ht||http://sso.test.com:8080/replylogin.html||http://my.web.com:8090/oa/oklogin.ht||http://my.web.com:8090/oa/login.ht
研究kisso跨域登录的心得的更多相关文章
- 在ASP.NET MVC3 中利用JSONP跨域登录WEB系统
在信息系统开发的时,根据相关业务逻辑难免会多系统之间互相登录.一般情况下我们需要在多系统之间使用多个用户名和密码.这样客户就需要在多个系统之间重复登陆.每次登录都需要输入用户名和密码.最近比较流行的就 ...
- memcache课程---4、php+memcache如何让用户跨域登录
memcache课程---4.php+memcache如何让用户跨域登录 一.总结 一句话总结: 让所有服务器共用一台memcache缓存,即可达到跨域的目的 1.session跨域:修改php配置文 ...
- 解决getJSON跨域登录Session丢失的问题
最近在做项目中发现,我用下面的代码异步请求到login.ashx: var memberUrl = rooturl + 'member.ashx?r=' + Math.random() + '& ...
- Web Api跨域登录问题
最近项目第一次尝试使用web api,照搬了一般mvc的Forms登录方式,在和前端对接的时候出现一个问题: 前端使用ajax调用登录接口完成登录后,再调用别的接口,被判断为未登录. 如果直接在浏览器 ...
- Json跨域登录问题的之Access-Control-Allow-Origin 站点跨域请求的问题
跨域调用json问题 闲暇之时,做了一个博客站点,站点发布网络之后程序功能完成,最后发现了一个跨域的问题,比如我使用abc.com打开系统,一切正常,后台没有任何文件请求报错问题,然后我又使用了www ...
- 关于跨域登录中获取COOKIES解析BUG
FormsAuthentication.Decrypt 报错 Length of the data to decrypt is invalid. 关于同域名不同服务器之间的登录,加密配置说明 ...
- 两系统用asp.net forms 身份验证方式实现跨域登录信息共享
1.两个系统的 web.config 都配置为 forms 验证方式( system.web —> authentication 节点) 2.在两个系统的Web.config里配置相同的 sys ...
- [1.6W字] 浏览器跨域请求限制的详细原理分析&寻找一种最简单的方式实现XHR跨域(9种方法, 附大招可以纯前端实现跨域!)
Title/ 浏览器跨域(CrossOrigin)请求的原理, 以及解决方案详细指南 #flight.Archives011 序: 最近看到又有一波新的创作活动了, 官方给出的话题中有一个" ...
- [1.6W字]浏览器跨域请求的原理, 以及解决方法(可以纯前端实现) #flight.Archives011
Title/ 浏览器跨域(CrossOrigin)请求的原理, 以及解决方案详细指南 #flight.Archives011 序: 最近看到又有一波新的创作活动了, 官方给出的话题中有一个" ...
随机推荐
- 网络存储(二)之ISCSI原理
组成 一个简单ISCSI系统大致由以下部分构成 ISCSI Initiator 或者 ISCSI HBA ISCSI Target 以太网交换机 一台或者多台服务器 结构图如下: iscsi服务器用来 ...
- Visual Studio 当前上下文中不存在名称“ConfigurationManager”
Visual Studio调试出现错误:当前上下文中不存在名称“ConfigurationManager” 解决方法: 1.System.Configuration引用这个dll参考:http://k ...
- python 培训之HTTP
1. urllib #!/usr/env/python # -*- coding:UTF-8 -*- from __future__ import print_function import sys ...
- sql自带函数语句
--取数值表达式的绝对值select abs(-41) 41select abs(41) 41select abs(-41.12) 41.12select abs(41.12 ...
- sqlserver插入时发生在“xxx”处关键发生错误
今天知道了一个小技巧,当你的数据库表名为user时会sqlserver的表发生冲突,所以因该将user这样用[user],ok 一切搞定 .
- Java——标签组件:JLabel
使用一个标签 import java.awt.Color; import java.awt.Dimension; import java.awt.Point; import javax.swing.J ...
- C#----XML操作小结
结点和元素的区别: * 结点和元素的区别: * 结点包括元素,结点可以是一个文本,也可以是一个属性,结点包括的类型在XmlNodeType中总结. * <root id="这是一个 ...
- python类相关
class A: def bar(self): print("BAR") self.f1() class B(A): def f1(self): print("B&quo ...
- ES6标准
1. ES6标准感觉越来越向传统语言靠拢了,以后写到ES6的标准都记录下: ,,]; // =>操作符 array.forEach(v => console.log(v)); 是不是简化了 ...
- GC算法
http://www.brpreiss.com/books/opus5/html/page424.html http://www.brpreiss.com/books/opus5/html/page4 ...