天天看點

單點登入的一種正常方法

正常的登入

正常的是通過session

步驟:

  1. 使用者在浏覽器登入
  2. 背景鑒權,若登入成功,則把使用者資訊寫入session,servlet自動生成JSESSIONID 傳回浏覽器;
  3. 浏覽器把JSESSIONID 寫入cookie

    說明:cookie是浏覽器的存儲檔案,存儲的隻是JSESSIONID,而不是使用者資訊;

JSESSIONID 隻是一個鈎子,使用者資訊其實存儲在伺服器端.

比如我在浏覽器登入之後,重新打開一個标簽頁,輸入相同的位址,仍然是登入狀态,因為标簽頁共享cookie.

也就是說我隻要擷取到JSESSIONID ,就可以擷取使用者隐私資訊,比如除使用者名以外的其他資訊(密碼,姓名,年齡等).也可以做一些敏感操作,比如修改密碼

浏覽器發送請求時會帶上cookie

這樣伺服器端才知道是否登入過:

單點登入的一種正常方法

例如,我擷取到JSESSIONID 之後,使用HTTP模拟發送請求:

單點登入的一種正常方法

伺服器端是如何判斷是否登入

/***
     * 判斷是否已登入
     * @param user2
     * @return
     */
    public static boolean isLogined(User user2,String loginFlag){
        if(ValueWidget.isNullOrEmpty(user2)||ValueWidget.isNullOrEmpty(user2.getUsername())
                ||loginFlag == null
                        ||( !loginFlag.equalsIgnoreCase(Constant2.FLAG_LOGIN_SUCCESS))){
            return false;
        }else{
            return true;
        }
    }

    /***
     * 判斷是否已登入
     * @param session
     * @return
     */
    public static boolean isLogined(HttpSession session){
        String loginFlag = (String) session
                .getAttribute(Constant2.SESSION_KEY_LOGINED_FLAG);
        User user2 = (User) session.getAttribute(Constant2.SESSION_KEY_LOGINED_USER);
        return isLogined(user2,loginFlag);
    }           

通過 cookie 實作單點登入

  1. 登入之前,會向伺服器請求一個随機token,同時傳回cookie,例如:

    CCC=63314c585041e889766fec6657879c; Expires=Mon, 21-Sep-2015 06:48:27 GMT; Path=/

  2. 登入時帶上這個cookie(即CCC=63314c585041e889766fec6657879c)
  3. 伺服器鑒權,登入成功之後,把登入憑證和CCC 綁定,

    即伺服器可以通過CCC 判斷是否登入,也可以通過CCC 擷取使用者敏感資訊.

這樣的話,隻要登入過,使用者不主動清除cookie,那就一直是登入狀态.

如果使用者主動清除了cookie,那就不是登入狀态了

單點登入的一種正常方法

詳細流程,邏輯

單點登入的一種正常方法

(1)登入前,浏覽器先向認證伺服器請求一個OTP,認證伺服器傳回OTP,同時傳回一個cookie給浏覽器;

(2)認證伺服器把OTP 和CCC(cookie) 挂鈎;

(3)登入時連同帶上OTP

(4)若登入成功,則認證伺服器傳回登入憑證(access token)給浏覽器;

(5)認證伺服器把CCC 和登入憑證挂鈎;

(6)通過CCC 可以判斷使用者是否有權限.

是以,

(a)可以通過CCC 擷取登入憑證

(b)也可以通過OTP 擷取登入憑證

根本原因:伺服器把OTP 和CCC(cookie) 挂鈎

那麼CCC記在什麼地方?

浏覽器

擷取OTP的接口傳回:

單點登入的一種正常方法

效果:

A和B是同一個公司的應用,

在同一個浏覽器中登入了應用A ,就可以在該浏覽器中直接通路應用B,而不用重新登入.

具體實作原理:

1,登入之前通路 認證系統的動态密碼接口,擷取動态密碼:auth_token

同時會傳回cookie:CCC ,目的:把浏覽器和 auth_token 挂鈎

等浏覽器通路其他應用時,把該CCC帶過去.

2,登入時參數包括(1)中傳回的auth_token ;

3,通路應用B 時,浏覽器會把cookie中的CCC傳過去,應用B 拿到之後,給認證系統認證,判斷是否登入;

若認證通過,則傳回使用者資訊

單點登入的一種正常方法
單點登入的一種正常方法

單點登入的目的

同一個公司的應用,隻需要登入一次。

比如我登入了阿裡雲,再打開淘寶 ,天貓或釘釘就不用重複登入(輸入使用者名和密碼)。

具體場景(Web)

單點登入的一種正常方法

小明登入了 Web應用A,再進入Web應用B時,不用重新輸入使用者名和密碼,就自動登入了。

問題:應用A和應用B要擁有相同的父域名嗎?

不用!!!

阿裡雲 和淘寶的域名就不一樣

具體實作(基于 cookie)

otp :one time password 就是一次一密

認證中心接口

接口一:jsonp接口,擷取 otp

請求方式:jsonp

擷取 otp,同時可以判斷是否已登入

http://auth.xxx.com/authentication/otp.jsonp?callbk=callbkMethod&clientId=

應用的clientId

傳回

{

"isLogined":true,

"otp":"433u23"

}

注意:jsonp 接口隻需要 clientId,不需要 secret

接口二:使用 otp登入

請求方式:post

http://auth.xxx.com/authentication/login.json

/>參數:

username:

password:

otp:接口一擷取的 otp

imgCode:圖形驗證碼

傳回:

"access_token":"",

"refresh_token":"",

"timeout":12000

...

接口三:opt 換取 access_token

http://auth.xxx.com/authentication/token.json?secret=

應用的secret&clientId=應用的clientId&opt=433u23

認證中心的作用

  1. 判斷是否已登入;
  2. otp 換access_token

未登入-登入流程

單點登入的一種正常方法

應用 A 已經登入,通路應用 B 時

單點登入的一種正常方法