zoukankan      html  css  js  c++  java
  • 研究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, "1000");
                    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

  • 相关阅读:
    quora 中有关angular与emberjs的精彩辩论
    迷你MVVM框架 avalonjs 0.94发布
    重写自己,减少判断 ---- 引发的思考
    JSON数据的优化
    记录全局错误
    Bat相关的项目应用
    C#中如何实现json转化时只处理部分属性
    JSON数据的处理中的特殊字符
    C# .net中json字符串和对象之间的转化方法
    VS调试 ---- 监视窗口、即时窗口、输出窗口
  • 原文地址:https://www.cnblogs.com/kzfy/p/5314592.html
Copyright © 2011-2022 走看看