sso單點登陸

同域下的單點登陸: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拿到用戶,若是成功拿到,則登陸成功,若是拿不到則返回登錄頁面。

相關文章
相關標籤/搜索