概述
所謂單點登錄(Single Sign On),簡稱為 SSO,就是在多個應用系統中,用户只需要登錄一次就可以訪問所有相互信任的應用系統。
任何系統接入SSO前需要完成兩個步驟,
1、主數據同步:這些主數據包括組織、賬户、權限信息等,從外部系統(可以是MDM、OA、HR等)同步本系統需要的這些數據。
2、實現SSO跳轉頁:門户系統會將令牌傳遞至當前系統,當前系統需要讀取令牌中的內容,在本系統完成賬户認證的操作。
組織與賬户同步
在單點登錄之前,首先要確保組織節點、賬户等信息已經同步到系統中,組織、賬户同步可以有很多中方式,這裏不再贅述。
TokenReader
SSO 對接工作的核心是讀取令牌(Token)值,並轉換為本系統的 userId。Foxnic-Web 已經對SSO集成做了很大的簡單化,僅需實現一個 TokenReader 即可,如下代碼所示。
import com.github.foxnic.api.transter.Result;
import org.github.foxnic.web.domain.oauth.User;
import org.github.foxnic.web.framework.sso.TokenReader;
import org.github.foxnic.web.language.Language;
import org.github.foxnic.web.proxy.oauth.UserServiceProxy;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class FoxnicTokenReader extends TokenReader {
/**
* 從請求中讀取賬户
* */
@Override
public String readUserId(HttpServletRequest request) {
// 讀取token
String account=request.getParameter("account");
// 把讀取的 token 轉換為 userId
Result<User> userResult = UserServiceProxy.api().getByAccount(account);
if(userResult.failure()) return null;
if(userResult.data()==null) return null;
// 最終返回 userId
return userResult.data().getId();
}
/**
* 從請求中讀取用户指定的語言
* */
@Override
public Language readLanguage(HttpServletRequest request) {
return Language.zh_cn;
}
}
系統配置
TokenReader 定義後需要在 YML 文件中的 security.token-resders 指定,可以指定一個,也可以指定多個,若指定多個則按順序調用。如下圖所示:
SSO 跳轉
在 Foxnic-Web 中,sso 跳轉也為 /sso-login.html 。針對不同的場景可以指定不同的參數值:
format :響應方式,可選值包括:html/json。html 通常用於pc端,完成登錄後,自動跳轉到指定頁面。json 方式主要用於移動端等非網頁的場合。
redirect : 指定登錄後的跳轉頁面,format 為 html 時有效,默認為 /index.html
登出與攔截
如果當前系統集成了單點登錄,那麼就需要在系統登出後或會話過期時跳轉到Portal自己的登錄頁,而不是當前系統的登錄頁。此時需要到系統管理下的系統參數設置兩個參數:
system.external.portal.enable:此參數開啓時,表示當前系統與外部Portal系統做了集成。
system.external.portal.loginURL:當 system.external.portal.enable 參數開啓時,指定外部門户的登錄頁面地址。
登錄身份識別
登錄身份識別與優先級的定義其實是常規登錄中(非SSO)的一個概念,當用户在登錄界面的輸入框輸入時,可能會輸入帳號,也可能輸入的是手機號、email、工號等。總之,從技術角度講,賬户表本身或任何與賬户表有關聯關係的表的字段,只要他唯一,就可以用於身份識別。那麼,如何確保正確識別呢? Foxnic-Web 使用了身份優先級配置這個特性。
Foxnic-Web 的常規登錄,目前支持 賬户ID,賬户名稱、手機號、工號,這四種,這些以支持的類型在 LoginIdentityType 枚舉類型中定義。為了避免識別的衝突,需要在試試時指定他們的優先級,YML 文件如下所示:
其中,賬户ID作為最高優先級無法修改,其它登錄身份識別標識可以通過YML文件調整識別的優先級。
相關項目
https://gitee.com/LeeFJ/foxnic
https://gitee.com/LeeFJ/foxnic-web
https://gitee.com/lank/eam