keycloak~關於社群登入的過程說明

张占岭發表於2024-08-08

keycloak將第三方登入(社群登入)進行了封裝,大體主要會經歷以下三個過程:

  1. 開啟社群認證頁面,輸入賬號密碼或者掃碼,完成社群上的認證
  2. 由社群進行302重定向,回到keycloak頁面
  3. keycloak與社群完成一次oauth2授權碼認證,透過社群返回的code來獲取token,再透過token來獲取社群上的使用者資訊,在這個過程中,社群不需要向keycloak公開使用者的密碼,這也是oauth2的安全性的表現
  4. keycloak檢查使用者是否與自己本地使用者繫結,如果未繫結,進入第一認證流進行註冊或者繫結現在有使用者,完成與社群的對應關係,在這個過程中,keycloak對發出FEDERATED_IDENTITY_LINK事件
  5. 使用者完成繫結之後,進行後一認證流,完成登入之後再做的事,如果使用者已經完成繫結,那麼第一認證流就不會進入了

回撥地址的擴充套件

  • 當社群認證成功後,會跳轉到keycloak的社群認證流
  • 當keycloak社群認證流完成後,會走到標準認證流
  • 標準認證流完成後,會重寫向到來源頁,並帶上keycloak的code碼
  • 這時,來源頁上有且只有code碼這個引數,如果希望擴充套件url上的引數,我們需要以下步驟

在社群回撥地址上新增loginType引數

  • org.keycloak.services.resources.IdentityBrokerService.finishBrokerAuthentication()方法新增對loginType的操作
private Response finishBrokerAuthentication(BrokeredIdentityContext context, UserModel federatedUser,
                                              AuthenticationSessionModel authSession, String providerId) {
    authSession.setAuthNote(AuthenticationProcessor.BROKER_SESSION_ID, context.getBrokerSessionId());
    authSession.setAuthNote(AuthenticationProcessor.BROKER_USER_ID, context.getBrokerUserId());

    this.event.user(federatedUser);

    context.getIdp().authenticationFinished(authSession, context);
    authSession.setUserSessionNote("loginType", providerId);
    ...
}
  • org.keycloak.protocol.oidc.OIDCLoginProtocol.authenticated()方法中,獲取loginType,並新增到回撥路徑的URL引數中
  code = OAuth2CodeParser.persistCode(session, clientSession, codeData);
  redirectUri.addParam(OAuth2Constants.CODE, code);
  // TODO: 登入成功後,將使用者登入方式追加到回撥頁面上
  if (authSession.getUserSessionNotes().containsKey("loginType")) {
    String loginType = authSession.getUserSessionNotes().get("loginType");
    redirectUri.addParam("loginType", loginType);
  }

FEDERATED_IDENTITY_LINK的完善

  • 預設的繫結訊息,內容比較少,不滿足我們的需求
{
  "time": 1723099954167,
  "type": "FEDERATED_IDENTITY_LINK",
  "realmId": "fabao",
  "clientId": "pkulaw",
  "userId": "e62a4ea6-c1c3-4f10-9136-8ceebba45339",
  "sessionId": null,
  "ipAddress": "111.198.143.194",
  "error": null,
  "details": {
    "identity_provider": "carsi",
    "identity_provider_identity": "student@pku.edu.cn",
    "code_id": "6668189e-4cd6-488e-8582-d28b87636b41",
    "username": "phone202408081431274571"
  }
}

擴充套件訊息,需要按以下步驟操作

  • 在org.keycloak.services.resources.IdentityBrokerService.afterFirstBrokerLogin方法中新增以下程式碼
  // 社群繫結現在有使用者後,發的事件FEDERATED_IDENTITY_LINK,我們需要新增一些擴充套件資訊
  event.detail(Details.IDENTITY_PROVIDER, providerId);
  event.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getBrokerUserId()); //event.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
  event.detail("identity_provider_username", context.getUsername());
  • 新增之後,我們為FEDERATED_IDENTITY_LINK事件訊息新增identity_provider_username
{
  "time": 1723101725866,
  "type": "FEDERATED_IDENTITY_LINK",
  "realmId": "fabao",
  "clientId": "pkulaw",
  "userId": "347c9e9e-076c-45e3-be74-c482fffcc6e5",
  "sessionId": null,
  "ipAddress": "10.10.80.81",
  "error": null,
  "details": {
    "identity_provider": "carsi",
    "identity_provider_username": "student@pku.edu.cn",
    "identity_provider_identity": "6zETJRPrWiBi7B85cCHPoVD7dyI\u003d",
    "code_id": "c344f279-9786-468b-a67e-fecf39c531b0",
    "username": "test"
  }
}

相關文章