同域下的單點登陸:spring
如今假設有兩個系統demo1,和demo2它們分別有本身的登錄方法以下:跨域
@PostMapping("/doLogin") public String doLogin(String username,String password,String url,HttpServletResponse response){ boolean result = SSOUtil.loginCheck(username,password); if(result){ Cookie cookie = new Cookie("ssoCookie","sso");//這裏的cookie須要必定的規則 cookie.setDomain(".bxw.com");//將cookie設置爲同父域 cookie.setPath("/");//設置cookie的路徑爲根路徑,也就是同域cookie都有效 response.addCookie(cookie); return "/success"; } return ""; }
在父域中設置cookie:cookie.setDomain(".bxw.com");//將cookie設置爲同父域springboot
在SSOUtil類中的loginCheck方法中檢驗用戶名密碼的正誤,若是檢驗經過則result的結果爲true,這樣在本域中會產生鍵爲ssoCookie,值爲sso的cookie(在sso中,不一樣用戶的鍵通常是相同的,而值則根據必定規則生成獨屬於本身的值,這裏爲了簡便統一寫爲sso)。cookie
如今假設demo1系統已經登陸,刷新demo2的登錄頁面。app
@GetMapping("/") public String toLogin(HttpServletRequest request){
Cookie[] cookies = request.getCookies(); if(SSOUtil.cookieCheck(cookies)){ return "/success"; }else{ return "/login"; } }
demo2在跳轉登陸頁面的方法中會首先檢驗是否有鍵爲ssoCookie,值爲sso的cookie,若是有的話,則返回登陸成功的界面不然返回登錄頁面。檢驗cookie方法以下。url
public static boolean cookieCheck(Cookie[] cookies){ if(cookies!=null){ for(Cookie cookie:cookies){ if("ssoCookie".equals(cookie.getName()) && "sso".equals(cookie.getValue())){ return true; } } } return false; }
同父域下的單點登陸:spa
與同域下的單點登陸相似,只不過在產生cookie時,須要設置cookie的域爲父域,具體方法以下:code
@PostMapping("/doLogin") public String doLogin(String username,String password,String url,HttpServletResponse response){ boolean result = SSOUtil.loginCheck(username,password); if(result){ Cookie cookie = new Cookie("ssoCookie","sso");//這裏的cookie須要必定的規則 cookie.setDomain(".bxw.com");//將cookie設置爲同父域 cookie.setPath("/");//設置cookie的路徑爲根路徑,也就是同域cookie都有效 response.addCookie(cookie); return "/success"; } return ""; }
須要修改cookie的驗證方法,這裏咱們假設有一個項目demo3專門用來檢驗cookie。由於子域能夠拿到父域的cookie,demo2遍歷域中的cookie,拿到鍵爲ssoCookie的cookie發送到demo3進行檢驗,這裏採用http請求。blog
@GetMapping("/") public String toLogin(HttpServletRequest request){ Cookie[] cookies = request.getCookies(); String result = "false"; if(cookies!=null){ for(Cookie cookie:cookies){ if("ssoCookie".equals(cookie.getName())){ Map<String,String> map = new HashMap<String,String>(); map.put("name",cookie.getName()); map.put("value",cookie.getValue()); result = SSOUtil.sendGet("http://client.bxw.com:7777/springboot/sso/checkCookie",map); } } } if("true".equals(result)){ return "/success"; }else{ return "/login"; } }
檢驗cookie其實應該寫一個過濾器,這裏爲了方便直接寫在跳轉登陸頁面的方法中,通常在參數過多的狀況下會採用map傳參。get
http請求以下,這裏用了get請求。
public static String sendGet(String url, Map<String,String> cookieMap) { String result = ""; BufferedReader in = null; try { StringBuffer urlNameString = new StringBuffer(url + "?"); for(Map.Entry<String,String> tmp:cookieMap.entrySet()){ urlNameString.append(tmp.getKey()+"="+tmp.getValue()+"&"); } String urlVal = urlNameString.substring(0,urlNameString.length()-1).toString(); URL realUrl = new URL(urlVal); // 打開和URL之間的鏈接 URLConnection connection = realUrl.openConnection(); // 設置通用的請求屬性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 創建實際的鏈接 connection.connect(); // 獲取全部響應頭字段 Map<String, List<String>> map = connection.getHeaderFields(); // 遍歷全部的響應頭字段 for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } // 定義 BufferedReader輸入流來讀取URL的響應 in = new BufferedReader(new InputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("發送GET請求出現異常!" + e); } // 使用finally塊來關閉輸入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; }
demo3中對demo2發出的http請求處理。
@GetMapping("/checkCookie") public String cookieCheck(HttpServletRequest request){ String CookieName = request.getParameter("name"); String CookieValue = request.getParameter("value"); Boolean flag = false;//驗證是否成功 if(CookieName.equals("ssoCookie") && CookieValue.equals("sso")){ flag = true; } return flag.toString(); } /* public void cookieCheck(HttpServletRequest request, HttpServletResponse response){ String CookieName = request.getParameter("name"); String CookieValue = request.getParameter("value"); Boolean flag = false;//驗證是否成功 if(CookieName.equals("ssoCookie") && CookieValue.equals("sso")){ flag = true; } try{ response.getWriter().print(flag); }catch (IOException e){ e.printStackTrace(); } }*/
跨域單點登陸:
若是是跨域的話,在demo2登錄時須要去請求demo1域中的單點登陸的cookie拿到用戶,若是成功拿到,則登陸成功,若是拿不到則返回登錄頁面。