研究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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM