摘要:時間年月日星期三說明本文部分內容均來自慕課網。慕課網教學示例源碼無個人學習源碼第一章概述課程介紹及介紹課程目標認識并理解及其應用,并能根據其實現原理自行實現。
時間:2017年3月22日星期三
說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com
教學示例源碼:無
個人學習源碼:https://github.com/zccodere/s...
課程目標
認識并理解SSO及其應用,并能根據其實現原理自行實現SSO。
學習內容
1.SSO的介紹和應用體驗(以新浪為例) SSO:一次登錄,處處穿梭 2.SSO的分類介紹的實現探討 同域SSO:不同的應用位于同一個域名下面 跨域SSO:不同的應用位于不同的域名下面 3.各種SSO的具體實現介紹的代碼示例
同域SSO圖示
1-2 SSO核心技術分析SSO的實現步驟和原理
以旅游是購買的通票為例:
SSO特點:
1.必須要登陸一次 2.票據與驗票機制
實現SSO的步驟拆解
關鍵:存儲票據(購票與存儲),查驗票據(是否有票與是否有效)
核心技術點實現原理:
比照旅游進行第二章:同域SSO 2-1 同域SSO準備工作
教學示例流程圖
個人學習流程圖
項目搭建
說明:教學使用SSH搭建演示項目,我在學習時使用springboot搭建,源碼可以在我的github上查看、下載、運行等。因為本節主要是講SSO單點登錄,并不是將項目搭建,所以搭建過程省略。
項目命名為:myssosamedomain
2-2 編寫統一登錄接口編寫校驗工具類
package com.myimooc.sso.web.util; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; /** * 登錄校驗工具類 * @author ZhangCheng * @date 2017-03-22 * @version V1.0 */ public class LoginCheck { /** 測試用戶名 */ public static final String USERNAME="user"; /** 測試密碼*/ public static final String PASSWORD="123"; /** Cookie鍵 */ public static final String COOKIE_NAME = "ssocookie"; /** Cookie值*/ public static final String COOKIE_VALUE = "sso"; /** * 登錄用戶名和密碼校驗 * @param username 用戶名 * @param password 密碼 * @return true用戶名和密碼正確;false用戶名或密碼錯誤 */ public static boolean checkLogin(String username,String password){ if(USERNAME.equalsIgnoreCase(username) && PASSWORD.equalsIgnoreCase(password)){ return true; } return false; } /** * 校驗Cookie * @param request * @return true正確;false錯誤 */ public static boolean checkCookie(HttpServletRequest request){ Cookie[] cookies = request.getCookies(); if( cookies == null){ return false; } for (Cookie cookie : cookies) { if(COOKIE_NAME.equals(cookie.getName()) && COOKIE_VALUE.equals(cookie.getValue())){ return true; } } return false; } }
編寫校驗控制器
package com.myimooc.sso.web.controller; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.myimooc.sso.web.util.LoginCheck; /** * SSO登錄控制器 * @author ZhangCheng * @date 2017-03-22 * @version V1.0 */ @Controller @RequestMapping("/sso") public class LoginController { /** * 處理用戶登錄請求 * @param username 用戶名 * @param password 密碼 * @param gotoUrl 登錄成功后請求路徑 * @param response * @return */ @PostMapping("/doLogin") public ModelAndView doLogin(String username,String password, String gotoUrl,HttpServletResponse response){ ModelAndView mv = new ModelAndView("login_fail"); // 校驗用戶名和密碼 boolean ok = LoginCheck.checkLogin(username, password); // 判斷是否登錄成功 if(ok){ Cookie cookie = new Cookie(LoginCheck.COOKIE_NAME,LoginCheck.COOKIE_VALUE); // 頂級域名下,所有應用都是可見的 cookie.setPath("/"); // 添加Cookie response.addCookie(cookie); mv.setViewName("redirect:"+gotoUrl); } return mv; } /** * 跳轉到登錄頁面 * @return */ @GetMapping("/login") public ModelAndView login(){ return new ModelAndView("login"); } }
編寫登錄頁面
登錄 請登錄
用戶名: 密 碼:
編寫登錄失敗頁面
2-3 編寫登錄頁面demo1和demo2控制器登錄失敗 登錄失敗
重新登錄
demo1控制器
package com.myimooc.sso.demo1; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.myimooc.sso.web.util.LoginCheck; /** * * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ @Controller public class DemoOneController { @RequestMapping("/demo1") public ModelAndView main(HttpServletRequest request) { ModelAndView mv = new ModelAndView(); if (LoginCheck.checkCookie(request)) { mv.setViewName("demo1"); return mv; } mv.addObject("gotoUrl", "/demo1"); mv.setViewName("login"); return mv; } }
demo2控制器
package com.myimooc.sso.demo2; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.myimooc.sso.web.util.LoginCheck; /** * * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ @Controller public class DemoTwoController { @RequestMapping("/demo2") public ModelAndView main(HttpServletRequest request) { ModelAndView mv = new ModelAndView(); if (LoginCheck.checkCookie(request)) { mv.setViewName("demo2"); return mv; } mv.addObject("gotoUrl", "/demo2"); mv.setViewName("login"); return mv; } }2-4 編寫DEMO1和DEMO2的主頁
demo1頁面
歡迎訪問demo1 這是demo1的主頁
demo2頁面
2-5 同域SSO最終效果演示歡迎訪問demo2 這是demo2的主頁
訪問demo1頁面需要登錄
訪問demo2頁面需要登錄
在demo1頁面處登錄
登錄成功,可以訪問demo1頁面
再次訪問demo2時,不需要登錄即可訪問
第三章:同父域SSO 3-1 準備工作教學示例流程圖
個人學習流程圖
通過修改host文件,來模擬實現父子域名。
文件路徑:C:WindowsSystem32driversetchosts
修改如下
說明:正常情況下,應該分別建立三個項目,對應demo1.x.com、demo2.x.com、check.x.com。但為了演示講解方便,我們通過項目里面對應的包名來區分是哪個項目。
項目搭建
項目命名為:myssosamefather
編寫消息響應類
package com.myimooc.sso.util; import java.io.Serializable; /** * 消息響應對象 * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ public class RespMessage implements Serializable{ private static final long serialVersionUID = 1L; /** 響應編號 */ private String respCode; /** 響應消息 */ private String respMsg; public String getRespCode() { return respCode; } public void setRespCode(String respCode) { this.respCode = respCode; } public String getRespMsg() { return respMsg; } public void setRespMsg(String respMsg) { this.respMsg = respMsg; } }
編寫登錄校驗工具類
package com.myimooc.sso.util; /** * 登錄校驗工具類 * * @author ZhangCheng * @date 2017-03-22 * @version V1.0 */ public class LoginCheck { /** 測試用戶名 */ public static final String USERNAME = "user"; /** 測試密碼 */ public static final String PASSWORD = "123"; /** Cookie鍵 */ public static final String COOKIE_NAME = "ssocookie"; /** Cookie值 */ public static final String COOKIE_VALUE = "sso"; /** * 登錄用戶名和密碼校驗 * * @param username * 用戶名 * @param password * 密碼 * @return true已登錄;false未登錄 */ public static boolean checkLogin(String username, String password) { if (USERNAME.equalsIgnoreCase(username) && PASSWORD.equalsIgnoreCase(password)) { return true; } return false; } /** * 校驗Cookie * @param cookieName * @param cookieValue * @return */ public static boolean checkCookie(String cookieName,String cookieValue) { if (cookieName == null || cookieName=="") { return false; } if (cookieValue == null || cookieValue=="") { return false; } if (COOKIE_NAME.equals(cookieName) && COOKIE_VALUE.equals(cookieValue)) { return true; } return false; } }
編寫http請求工具類
package com.myimooc.sso.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import com.alibaba.fastjson.JSONObject; /** * http工具類 * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ public class HttpUtils { /** * 向指定url路徑發起get請求,校驗cookie * @param url 路徑 * @param cookieName * @param cookieValue * @return */ public static RespMessage doGet(String url,String cookieName,String cookieValue){ RespMessage respMessage = new RespMessage(); HttpURLConnection httpURLConnection = null; URL targetUrl = null; try{ targetUrl = new URL(url+"?cookieName="+cookieName+"&cookieValue="+cookieValue); httpURLConnection = (HttpURLConnection) targetUrl.openConnection(); httpURLConnection.setRequestMethod("GET"); httpURLConnection.connect(); InputStream in = httpURLConnection.getInputStream(); InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr); StringBuffer sb = new StringBuffer(); String temp = null; while((temp=br.readLine())!=null){ sb.append(temp); } br.close(); isr.close(); in.close(); JSONObject resultJson = JSONObject.parseObject(sb.toString()); respMessage.setRespCode(resultJson.getString("respCode")); respMessage.setRespMsg(resultJson.getString("respMsg")); return respMessage; }catch (Exception e) { respMessage.setRespCode("500"); respMessage.setRespMsg("Cookie校驗請求失敗"); return respMessage; }finally { if(httpURLConnection !=null){ httpURLConnection.disconnect(); } } } }
check.x.com:編寫認證中心控制器
package com.myimooc.sso.check.x.com; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import com.myimooc.sso.util.LoginCheck; import com.myimooc.sso.util.RespMessage; /** * SSO登錄控制器 * * @author ZhangCheng * @date 2017-03-22 * @version V1.0 */ @Controller @RequestMapping("/sso") public class LoginController { /** * 處理用戶登錄請求 * * @param username * 用戶名 * @param password * 密碼 * @param gotoUrl * 登錄成功后請求路徑 * @param response * @return */ @PostMapping("/doLogin") public ModelAndView doLogin(String username, String password, String gotoUrl, HttpServletResponse response) { ModelAndView mv = new ModelAndView("login_fail"); // 校驗用戶名和密碼 boolean ok = LoginCheck.checkLogin(username, password); // 判斷是否登錄成功 if (ok) { Cookie cookie = new Cookie(LoginCheck.COOKIE_NAME, LoginCheck.COOKIE_VALUE); // 設置在父域下面 cookie.setDomain("x.com"); // 頂級域名下,所有應用都是可見的 cookie.setPath("/"); // 添加Cookie response.addCookie(cookie); mv.setViewName("redirect:" + gotoUrl); } return mv; } /** * 校驗cookie * @param cookieName * @param cookieValue * @param response * @return */ @GetMapping("/checkCookie") @ResponseBody public RespMessage checkCookie(String cookieName,String cookieValue,HttpServletResponse response){ RespMessage result = new RespMessage(); result.setRespCode("500"); result.setRespMsg("CookieName或CookieValue無效"); boolean isOk = LoginCheck.checkCookie(cookieName, cookieValue); if(isOk){ result.setRespCode("200"); result.setRespMsg("Cookie有效"); } return result; } /** * 跳轉到登錄頁面 * * @return */ @GetMapping("/login") public ModelAndView login() { return new ModelAndView("login"); } }3-3 編寫demo1和demo2項目的控制層
demo1.x.com:編寫demo1項目控制器
package com.myimooc.sso.demo1.x.com; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.myimooc.sso.util.HttpUtils; import com.myimooc.sso.util.RespMessage; /** * * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ @Controller public class DemoOneController { @RequestMapping("/demo1") public ModelAndView main(HttpServletRequest request) { ModelAndView mv = new ModelAndView(); //校驗cookie是否為空 Cookie[] cookies = request.getCookies(); if(cookies != null && cookies.length > 0){ //校驗cookie是否存在 for(Cookie cookie : cookies){ if("ssocookie".equals(cookie.getName())){ //向校驗服務器發送校驗請求 String url = "http://check.x.com:8080/sso/checkCookie"; RespMessage respMessage = HttpUtils.doGet(url, cookie.getName(), cookie.getValue()); if("200".equals(respMessage.getRespCode())){ mv.setViewName("demo1"); return mv; } } } } mv.addObject("gotoUrl", "http://demo1.x.com:8080/demo1"); mv.setViewName("login"); return mv; } }
demo2.x.com:編寫demo2項目控制器
package com.myimooc.sso.demo2.x.com; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.myimooc.sso.util.HttpUtils; import com.myimooc.sso.util.RespMessage; /** * * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ @Controller public class DemoTwoController { @RequestMapping("/demo2") public ModelAndView main(HttpServletRequest request) { ModelAndView mv = new ModelAndView(); //校驗cookie是否為空 Cookie[] cookies = request.getCookies(); if(cookies != null && cookies.length > 0){ //校驗cookie是否存在 for(Cookie cookie : cookies){ if("ssocookie".equals(cookie.getName())){ //向校驗服務器發送校驗請求 String url = "http://check.x.com:8080/sso/checkCookie"; RespMessage respMessage = HttpUtils.doGet(url, cookie.getName(), cookie.getValue()); if("200".equals(respMessage.getRespCode())){ mv.setViewName("demo2"); return mv; } } } } mv.addObject("gotoUrl", "http://demo2.x.com:8080/demo2"); mv.setViewName("login"); return mv; } }3-4 編寫登錄頁
3-5 同父域情況下的SSO效果演示Insert title here 請登錄
用戶名: 密 碼:
請注意觀察瀏覽器URL地址
訪問demo1.x.com:需要登錄
訪問demo2.x.com:需要登錄
在demo1.x.com處登錄成功后,跳轉至demo1頁面
再訪問demo2.x.com的demo2頁面時,不再需要登錄了
第四章:跨域SSO的實現 4-1 準備工作教學示例流程圖
個人學習流程圖
通過修改host文件,來模擬實現跨域應用。
文件路徑:C:WindowsSystem32driversetchosts
修改如下
說明:正常情況下,應該分別建立三個項目,對應www.a.com、www.b.com、www.x.com。但為了演示講解方便,我們通過項目里面對應的包名來區分是哪個項目。
項目搭建
項目命名為:myssocrossdomain
完成后的目錄結構如下
4-2 編寫統一登錄接口編寫消息響應類
package com.myimooc.sso.util; import java.io.Serializable; import java.util.Map; /** * 消息響應對象 * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ public class RespMessage implements Serializable{ private static final long serialVersionUID = 1L; /** 響應編號 */ private String respCode; /** 響應消息 */ private String respMsg; /** 響應數據 */ private MaprespArgs; public String getRespCode() { return respCode; } public void setRespCode(String respCode) { this.respCode = respCode; } public String getRespMsg() { return respMsg; } public void setRespMsg(String respMsg) { this.respMsg = respMsg; } public Map getRespArgs() { return respArgs; } public void setRespArgs(Map respArgs) { this.respArgs = respArgs; } @Override public String toString() { return "RespMessage [respCode=" + respCode + ", respMsg=" + respMsg + ", respArgs=" + respArgs + "]"; } }
編寫http請求工具類
package com.myimooc.sso.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; import com.alibaba.fastjson.JSONObject; /** * Http請求工具類 * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ public class HttpUtils { /** * 向指定url路徑發起get請求 * @param url 請求路徑 * @param param 請求參數 * @return */ public static RespMessage doGet(String url,Mapparam){ RespMessage respMessage = new RespMessage(); HttpURLConnection httpURLConnection = null; URL targetUrl = null; try{ // 拼裝請求參數 StringBuffer targetUrlStr = new StringBuffer(url).append("?"); for(Map.Entry entry : param.entrySet()){ targetUrlStr.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } url = targetUrlStr.substring(0,targetUrlStr.length()-1); targetUrl = new URL(url); httpURLConnection = (HttpURLConnection) targetUrl.openConnection(); httpURLConnection.setRequestMethod("GET"); httpURLConnection.connect(); InputStream in = httpURLConnection.getInputStream(); InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr); StringBuffer sb = new StringBuffer(); String temp = null; while((temp=br.readLine())!=null){ sb.append(temp); } br.close(); isr.close(); in.close(); JSONObject resultJson = JSONObject.parseObject(sb.toString()); respMessage.setRespCode(resultJson.getString("respCode")); respMessage.setRespMsg(resultJson.getString("respMsg")); JSONObject resultJsonMap = JSONObject.parseObject(resultJson.getString("respArgs")); respMessage.setRespArgs(resultJsonMap); return respMessage; }catch (Exception e) { respMessage.setRespCode("500"); respMessage.setRespMsg("請求發起失敗"); return respMessage; }finally { if(httpURLConnection !=null){ httpURLConnection.disconnect(); } } } }
www.x.com:編寫認證中心校驗工具類
package com.myimooc.sso.www.x.com; /** * 登錄校驗工具類 * * @author ZhangCheng * @date 2017-03-22 * @version V1.0 */ public class LoginCheck { /** 測試用戶名 */ public static final String USERNAME = "user"; /** 測試密碼 */ public static final String PASSWORD = "123"; /** Cookie鍵 */ public static final String COOKIE_NAME = "ssocookie"; /** Cookie值 */ public static final String COOKIE_VALUE = "sso"; /** * 登錄用戶名和密碼校驗 * * @param username * 用戶名 * @param password * 密碼 * @return true已登錄;false未登錄 */ public static boolean checkLogin(String username, String password) { if (USERNAME.equalsIgnoreCase(username) && PASSWORD.equalsIgnoreCase(password)) { return true; } return false; } /** * 校驗Cookie * @param cookieName * @param cookieValue * @return */ public static boolean checkCookie(String cookieName,String cookieValue) { if (cookieName == null || cookieName=="") { return false; } if (cookieValue == null || cookieValue=="") { return false; } if (COOKIE_NAME.equals(cookieName) && COOKIE_VALUE.equals(cookieValue)) { return true; } return false; } }
www.x.com:編寫認證中心控制器
package com.myimooc.sso.www.x.com; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.myimooc.sso.util.RespMessage; /** * SSO登錄控制器 * * @author ZhangCheng * @date 2017-03-22 * @version V1.0 */ @Controller @RequestMapping("/sso") public class LoginController { /** * 校驗用戶信息 * @param param * @return */ @GetMapping("/doLogin") @ResponseBody public RespMessage doLogin(String username,String password) { RespMessage result = new RespMessage(); result.setRespCode("500"); result.setRespMsg("用戶名或密碼錯誤"); // 校驗用戶名和密碼 boolean ok = LoginCheck.checkLogin(username,password); // 判斷是否登錄成功 if (ok) { result.setRespCode("200"); result.setRespMsg("用戶名和密碼正確"); List
www.x.com:編寫登錄頁
登錄 請登錄
用戶名: 密 碼:
www.x.com:編寫login.js
/** * 登錄js */ $(function(){ var ctx = $("#ctx").val(); $("#login_button").click(function(){ login(); }); }); function login(){ // 獲取登錄信息 var username=$("#username_input").val(); var password=$("#password_input").val(); var path=$("#path_input").val(); var gotoUrl=$("#gotoUrl_input").val(); var requesturl="/a/doLogin"; $.ajax({ type:"POST", async:false,//發送同步請求 url:requesturl, data:"username="+username+"&password="+password, success:function(result){ // 登錄失敗 if(result.respCode != 200 ){ alert(result.respMsg); return; } // 登錄成功 var targetCookies = result.respArgs.targetCookies; // 向服務器發出添加cookie請求 $.each(targetCookies,function(i,targetCookie){ var targetUrl = targetCookie.targetUrl; var cookieName = targetCookie.cookieName; var cookieValue = targetCookie.cookieValue; creat(targetUrl,cookieName,cookieValue); }); } }); // 跳轉到目標頁 window.location.href=gotoUrl; } /** js利用iframe實現跨域添加cookie */ function creat(targetUrl,cookieName,cookieValue){ var iframe = document.createElement("iframe"); var targetSrc = targetUrl+"?"+"cookieName="+cookieName+"&cookieValue="+cookieValue; iframe.src=targetSrc; document.body.appendChild(iframe); }4-3 編寫登錄校驗接口
www.a.com:編寫控制器
package com.myimooc.sso.www.a.com; import java.util.HashMap; import java.util.Map; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import com.myimooc.sso.util.RespMessage; import com.myimooc.sso.util.HttpUtils; /** * * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ @Controller @RequestMapping("/a") public class DemoOneController { /** * 跳轉到demo1的主頁 * @param request * @return */ @RequestMapping("/demo1") public ModelAndView demo1(HttpServletRequest request) { ModelAndView mv = new ModelAndView(); //校驗cookie是否為空 Cookie[] cookies = request.getCookies(); if(cookies != null && cookies.length > 0){ //校驗cookie是否存在 for(Cookie cookie : cookies){ if("ssocookie".equals(cookie.getName())){ // 封裝請求參數 Mapparam = new HashMap (); param.put("cookieName", cookie.getName()); param.put("cookieValue", cookie.getValue()); // 向校驗服務器發送校驗請求 String url = "http://www.x.com/sso/checkCookie"; RespMessage respMessage = HttpUtils.doGet(url, param); // 校驗通過 if("200".equals(respMessage.getRespCode())){ mv.setViewName("demo1"); return mv; } } } } // 登錄失敗重新登錄 String path = request.getContextPath(); mv.addObject("contextPath",path); mv.addObject("path","a"); mv.addObject("gotoUrl", "http://www.a.com/a/demo1"); mv.setViewName("login"); return mv; } /** * 用戶登錄 * @param param * @return */ @PostMapping(value="/doLogin") @ResponseBody public RespMessage doLogin(@RequestParam Map param){ // 向校驗服務器發送校驗請求 String url = "http://www.x.com/sso/doLogin"; RespMessage respMessage = HttpUtils.doGet(url, param); System.out.println("SSO服務器響應消息:"+respMessage); return respMessage; } /** * 想當前域添加cookie * @param cookieName * @param cookieValue * @param response */ @RequestMapping(value="/addCookie") public void addCookie(String cookieName,String cookieValue,HttpServletResponse response){ Cookie cookie = new Cookie(cookieName,cookieValue); cookie.setPath("/"); response.addCookie(cookie); } }
www.b.com:編寫控制器
package com.myimooc.sso.www.b.com; import java.util.HashMap; import java.util.Map; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import com.myimooc.sso.util.HttpUtils; import com.myimooc.sso.util.RespMessage; /** * * @author ZhangCheng * @date 2017-04-02 * @version V1.0 */ @Controller @RequestMapping("/b") public class DemoTwoController { @RequestMapping("/demo2") public ModelAndView main(HttpServletRequest request) { ModelAndView mv = new ModelAndView(); //校驗cookie是否為空 Cookie[] cookies = request.getCookies(); if(cookies != null && cookies.length > 0){ //校驗cookie是否存在 for(Cookie cookie : cookies){ if("ssocookie".equals(cookie.getName())){ // 封裝請求參數 Map4-4 跨域SSO效果演示param = new HashMap (); param.put("cookieName", cookie.getName()); param.put("cookieValue", cookie.getValue()); // 向校驗服務器發送校驗請求 String url = "http://www.x.com/sso/checkCookie"; RespMessage respMessage = HttpUtils.doGet(url, param); // 校驗通過 if("200".equals(respMessage.getRespCode())){ mv.setViewName("demo2"); return mv; } } } } // 登錄失敗重新登錄 mv.addObject("contextPath",request.getContextPath()); mv.addObject("path","b"); mv.addObject("gotoUrl", "http://www.b.com/b/demo2"); mv.setViewName("login"); return mv; } /** * 用戶登錄 * @param param * @return */ @PostMapping(value="/doLogin") @ResponseBody public RespMessage doLogin(@RequestParam Map param){ // 向校驗服務器發送校驗請求 String url = "http://www.x.com/sso/doLogin"; RespMessage respMessage = HttpUtils.doGet(url, param); System.out.println("SSO服務器響應消息:"+respMessage); return respMessage; } /** * 向當前域添加cookie * @param cookieName * @param cookieValue * @param response */ @RequestMapping(value="/addCookie") public void addCookie(String cookieName,String cookieValue,HttpServletResponse response){ Cookie cookie = new Cookie(cookieName,cookieValue); cookie.setPath("/"); response.addCookie(cookie); } }
注意觀察瀏覽器URL地址
訪問www.a.com的a項目需要登錄
訪問www.b.com的b項目需要登錄
在www.a.com域登錄
登錄成功
www.b.com域即可直接訪問,免登陸
第五章:課程總結 5-1 課程總結1.核心是COOKIE,需要注意設置的域、位置和安全性
注意COOKIE的加密
2.應用群的安全性問題:木桶效應
即應用群的安全性受限于某個安全性最低的應用
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66947.html
時間:2017年07月09日星期日說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學源碼:無學習源碼:https://github.com/zccodere/s... 第一章:概述 1-1 課程概述 主要內容 驗證碼歷史 課程內容 不同方案對比 設計與實現 總結 1-2 驗證碼歷史 驗證碼歷史 無驗證碼:垃圾騷擾 Luis von Ahn:Captcha 不斷...
摘要:時間年月日星期六說明本文部分內容均來自慕課網。第六章公眾號與開發平臺關聯公眾號與開放平臺關聯情景說明當使用端進行微信授權登錄時,得到的和公眾號授權登錄時得到的不一樣。 時間:2017年08月12日星期六說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學源碼:無學習源碼:https://github.com/zccodere/s... 第一章:課程介紹...
摘要:此時,用戶想要訪問系統受限的資源比如說訂單功能,訂單功能需要登錄后才能訪問,系統發現用戶并沒有登錄,于是重定向到認證中心,并將自己的地址作為參數。 前言 只有光頭才能變強。文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y 在我實習之前我就已經在看單點登錄的是什么了,但是實習的時候一直在忙其他的事,所以有幾個網站就...
摘要:此時,用戶想要訪問系統受限的資源比如說訂單功能,訂單功能需要登錄后才能訪問,系統發現用戶并沒有登錄,于是重定向到認證中心,并將自己的地址作為參數。前言 只有光頭才能變強。 文本已收錄至我的GitHub倉庫,歡迎Star:github.com/ZhongFuChen… 在我實習之前我就已經在看單點登錄的是什么了,但是實習的時候一直在忙其他的事,所以有幾個網站就一直躺在我的收藏夾里邊: ...
摘要:此時,用戶想要訪問系統受限的資源比如說訂單功能,訂單功能需要登錄后才能訪問,系統發現用戶并沒有登錄,于是重定向到認證中心,并將自己的地址作為參數。前言 只有光頭才能變強。 文本已收錄至我的GitHub倉庫,歡迎Star:github.com/ZhongFuChen… 在我實習之前我就已經在看單點登錄的是什么了,但是實習的時候一直在忙其他的事,所以有幾個網站就一直躺在我的收藏夾里邊: ...
閱讀 1411·2021-10-08 10:04
閱讀 733·2021-09-07 09:58
閱讀 2912·2019-08-30 15:55
閱讀 2424·2019-08-29 17:21
閱讀 2126·2019-08-28 18:04
閱讀 3075·2019-08-28 17:57
閱讀 715·2019-08-26 11:46
閱讀 2228·2019-08-23 17:20