DingTalk、WeCom、Lark、InfoflowおよびWeChatによるCasdoorでのOAuthログイン
Casdoorには、DingTalk、WeCom (WeChat Work)、Lark (Feishu)、Baidu Infoflow、およびWeChat用の組み込みOAuthプロバイダーがあります。各ベンダーの開発者コンソールでアプリを作成し、その認証情報をCasdoorプロバイダーに貼り付け、プロバイダーをアプリケーションに追加します。Casdoorはベンダーのフローを実行し(デスクトップでのQRスキャン、またはベンダー自身のクライアント内でのサインイン)、ベンダーが必要な場合に企業アクセストークンを取得し、ベンダーのユーザーIDをCasdoorユーザーにマッピングします。あなたのアプリケーションはCasdoorとOIDCでのみ通信し、DingTalkヘッダー、WeCom user_ticket、またはWeChat unionidを見ることはありません。DingTalk、WeCom、およびLarkでは、シンクナーが最初のサインインの前に組織ディレクトリ全体をインポートすることもできます。
一目でわかる概要
| プロバイダー | 作成するアプリ | ユーザーがサインインする場所 | CasdoorユーザーをリンクするID | メールアドレスと電話番号 | ディレクトリシンクナー |
|---|---|---|---|---|---|
| DingTalk | 内部アプリ (AppKey, AppSecret) | DingTalkサインインページ、login.dingtalk.com | openId; unionidはユーザー名になります | プロフィールから取得され、企業ディレクトリに置き換えられます。検証済みとして扱われます | はい |
| WeCom | 自社開発アプリ (CorpID, Secret, AgentId)、またはサードパーティ | Webログイン (QR、またはWeComデスクトップからのクイックログイン)、またはWeCom内のサイレントサインイン | userid (内部)、open_userid (サードパーティ) | snsapi_privateinfoがある場合のみメール。電話は読み取られません | はい |
| Lark / Feishu | カスタムアプリ (App ID, App Secret) | Larkサインインページ、FeishuまたはLark Global | open_id; ユーザー名はuser_id、なければunion_id、それもなければopen_id | アプリが連絡先権限を持っている場合はい | はい |
| Baidu Infoflow | 内部アプリ (CorpID, Secret, AgentID) | Infoflow認可ページ | userid、ユーザー名としても使用されます | メールアドレス | いいえ |
| オープンプラットフォーム上のウェブサイトアプリ、および公式アカウント | PCでのQRスキャン; 公式アカウントを通じてWeChatブラウザ内 | unionid、なければopenid | どちらもなし | いいえ |
各設定手順はドキュメントに記載されています: DingTalk、WeCom、Lark、Infoflow、およびWeChat。この記事では、それぞれの裏側で何が起きているかを説明します。
アプリケーションが見るもの
表にあるすべてのプロバイダーは同じ方法で終わります。Casdoorはベンダーのコードを交換し、組織内でユーザーを検索または作成し、その後、独自の認可コードをアプリに発行します。アプリはそれをCasdoorのトークンエンドポイントで引き換え、アプリケーションの証明書で署名されたCasdoor IDトークンとアクセストークンを取得します。クレームはCasdoorユーザーレコードから来ています: 名前、表示名、メールアドレス、電話番号、アバター、グループ。
バックエンドコードは5つすべてで同じです。任意のOIDCライブラリが機能します。OAuth 2.0 and OIDC referenceを参照し、完全なウォークスルーについてはSpring Boot SSO with OIDCを参照してください。後でベンダー自身のAPIが必要になる場合は、Casdoorはプロバイダーのアクセストークンをユーザーに保存します。これはOAuth providersで説明されています。
DingTalk
DingTalkオープンプラットフォームで内部アプリを作成し、そのAppKeyとAppSecretをプロバイダーのClient IDとClient secretにコピーします。サインインページは、ユーザーをscope=openidおよびprompt=login consent付きのhttps://login.dingtalk.com/oauth2/authへ送信します。ユーザーが確認した後、Casdoorは4つの呼び出しを行います:
POST https://api.dingtalk.com/v1.0/oauth2/userAccessTokenは、コードをユーザートークンに変換します。GET https://api.dingtalk.com/v1.0/contact/users/meは、ユーザーのopenId、unionId、ニックネーム、アバター、メールアドレス、携帯電話番号を返します。これにはアプリに対するContact.User.Read権限が必要です。appKeyとappSecretを含むPOST https://api.dingtalk.com/v1.0/oauth2/accessTokenは、企業(アプリ)アクセストークンを返します。- そのトークンを使用すると、
topapi/user/getbyunionidはunionidを企業のuseridにマッピングし、topapi/v2/user/getはディレクトイレコードを読み取ります。
ユーザーがアプリを所有する組織のメンバーでない場合、ステップ4はDingTalkエラー60121で失敗し、サインインは停止します。ディレクトリ検索が成功した場合、ディレクトリのメールアドレスと携帯電話番号が個人のものに置き換えられ、unionidがユーザー名になり、役職は追加のクレームとして保持されます。
企業アクセストークンとそのヘッダー
DingTalkには、同じトークンを異なる場所で受け取る2つのAPI世代があります:
GET https://api.dingtalk.com/v1.0/contact/users/me
x-acs-dingtalk-access-token: <token>
POST https://oapi.dingtalk.com/topapi/v2/user/get?access_token=<token>
Content-Type: application/json
{"userid": "<userid>"}
api.dingtalk.com上の新しいAPIは、x-acs-dingtalk-access-tokenヘッダーからのみトークンを読み取ります。そのヘッダーなしで(またはAuthorization: Bearer付きで)呼び出すと、ヘッダーの名前を示すAuthenticationFailed.MissingParameterと応答します。古いoapi.dingtalk.comエンドポイントは、依然としてaccess_tokenクエリパラメータを受け取ります。Casdoorは両方を使用します: users/meにはヘッダー、2つのtopapi呼び出しにはクエリパラメータを使用し、v1.0/oauth2/accessTokenからの企業トークンを両方の場所で使用します。DingTalkはこのトークンの有効期限を7,200秒と文書化しており、アプリごとにキャッシュすることを求めています。また、DingTalkは古いgettokenエンドポイントを新規アプリ向けにレガシーとしてマークしています。
CasdoorはDingTalkが返すメールアドレスと電話番号を検証済みとしてカウントするため、デフォルトのバインディングルール(まずメール、次に電話)により、既存のユーザーにDingTalkサインインを添付できます。how Casdoor links accountsを参照してください。
WeCom (WeChat Work)
WeComプロバイダーにはSub typeとMethodがあります:
- Internal と Normal の組み合わせでは、ユーザーは
login_type=CorpAppを指定した WeCom Web ログイン (login.work.weixin.qq.com/wwlogin/sso/login) にリダイレクトされます。WeCom は QR コードを表示するか、WeCom デスクトップアプリが実行中でサインインしている場合はワンクリックのクイックログインを提供します。 - Internal と Silent の組み合わせでは、アプリの
agentidを使用してopen.weixin.qq.com/connect/oauth2/authorizeが利用されます。これは WeCom クライアント内で開かれるページに推奨される設定です。 - Third-party では、
login_type=ServiceAppとサービスプロバイダーのシークレット (get_provider_token) が使用され、続いてget_login_infoが呼び出されて、ユーザーをopen_useridでリンクします。
内部アプリの場合、Casdoor は CorpID とアプリの Secret を使って cgi-bin/gettoken から企業トークンを取得し、その後コードをメンバーの userid と交換します。メンバーでない訪問者は代わりに openid を返すため、Casdoor はサインインを拒否します。トークンはすべての WeCom 呼び出しでクエリパラメータとして渡されます。WeCom によれば、トークンの有効期間は通常 7,200 秒であり、gettoken にはレート制限があります。
メールアドレスについては慎重な計画が必要です。WeCom は、2022-06-20 20:00 以降に作成された自社開発アプリに対して、メンバー読み取り API (user/get) からアバター、性別、携帯電話番号、メールアドレスの返却を停止しました。メールアドレスを取得するには、プロバイダーのスコープを snsapi_privateinfo に設定します。これにより WeCom は user_ticket を返し、Casdoor はそれを getuserdetail で引き換えます。WeCom では、管理者がアプリ設定で機密フィールドを選択し、メンバーが同意する必要があります。また、これらのフィールドはサードパーティアプリには決して提供されません。Casdoor は WeCom から電話番号を読み取っていません。
Lark と Feishu
Feishu Open Platform または Lark グローバルプラットフォームでカスタムアプリを作成し、App ID と App Secret をコピーします。Lark (open.larksuite.com) のプロバイダーでは Use global endpoint をオンにし、Feishu (open.feishu.cn) の場合はオフのままにしてください。
Casdoor はまず auth/v3/tenant_access_token/internal から tenant_access_token を取得し、次にそのトークンを Authorization: Bearer ヘッダーに入れて authen/v1/access_token にコードを投稿します。レスポンスには open_id、union_id、user_id、メール、企業メール、携帯電話が含まれます。Feishu は、アプリが対応する権限を持っている場合にのみ機密情報を返します:
| フィールド | Feishu 権限 |
|---|---|
user_id | contact:user.employee_id:readonly |
email | contact:user.email:readonly |
enterprise_email | contact:user.employee:readonly |
mobile | contact:user.phone:readonly |
これらの権限がない場合でもサインインは機能します。ユーザー名は user_id から union_id、さらに open_id へとフォールバックします。Casdoor は email が空の場合は enterprise_email を使用し、メールと電話の両方を検証済みとして扱います。Feishu は現在 v1 の access_token エンドポイントを歴史的バージョンとしてリストしていますが、依然として提供されています。
Baidu Infoflow
Infoflow (如流) は Baidu のワークプレイスアプリです。Infoflow 管理画面でアプリを登録し、アドレス帳へのアクセス権限を付与してから、CorpID、Secret、AgentID を Internal サブタイプを持つプロバイダーにコピーします。サインインページは https://xpc.im.baidu.com/oauth2/authorize に移動します。その後、Casdoor は CorpID と Secret を使って qy.im.baidu.com/api/gettoken を呼び出し、コードと AgentID を api/user/getuserinfo でメンバーの userid と交換し、名前、アバター、メールを api/user/get から読み取ります。userid はリンク ID とユーザー名の両方になり、メールは検証済みとしてカウントされます。Infoflow 用のシンカーはないため、ユーザーは初回サインイン時に作成されます。
微信
WeChat ログインには2つの側面があり、通常は両方とも必要になります:
- Web サブタイプ: WeChat オープンプラットフォーム上のウェブサイトアプリです。PC のサインインページでは、
scope=snsapi_loginを指定したopen.weixin.qq.com/connect/qrconnectからの QR コードが表示され、ユーザーは WeChat アプリでスキャンします。 - Mobile サブタイプ、または同じプロバイダーの2番目の認証情報ペア: オフィシャルアカウントです。WeChat ブラウザー内では QR コードは無意味なため、Casdoor はオフィシャルアカウントの AppID を含む
snsapi_userinfoでconnect/oauth2/authorizeに切り替えます。オフィシャルアカウントが設定されていない場合、Casdoor は外部ブラウザーでページを開くようユーザーに指示します。
WeChat はメールや電話を返さず、openid、unionid、ニックネーム、アバターのみを返します。Casdoor は WeChat が unionid を送信する場合はそれによってユーザーをリンクし、ない場合は openid にフォールバックしますが、アプリごとの openid も保存します。WeChat は、1つのオープンプラットフォームアカウント下にあるすべてのアプリとオフィシャルアカウント間でユーザーに同じ unionid を付与するため、ウェブサイトアプリとオフィシャルアカウントを同じオープンプラットフォームアカウントにバインドしてください。そうしないと、PC でスキャンした後にスマートフォンでサインインしたユーザーが、2人の Casdoor ユーザーとして扱われてしまいます。
ディレクトリの事前インポート
DingTalk、WeCom、Lark の場合、シンカー を使用してスケジュールに従ってユーザーと部門をプルできるため、サインイン前にアカウントが存在し、部門は Casdoor グループになります。各シンカーはベンダーのディレクトリ API から企業トークンを使用します: DingTalk シンカー は部門を再帰的に走査し、WeCom シンカー は 2022-08-15 以降に作成されたアプリに対して user/list_id と user/get にフォールバックし、Lark シンカー には Feishu または Lark グローバルを選択するための Lark platform 設定があります。
WeCom シンカーは、WeCom プロバイダーがリンクに使用する userid を書き込むため、同期されたユーザーは直接サインインできます。DingTalk と Lark のシンカーはディレクトリの userid / user_id を保存しますが、サインイン時は openId / open_id でリンクします。これらの初回サインインは、メールまたは電話番号によるバインディングルールを通じて一致を確認します。これは両方のプロバイダーがそれらを検証済みとして報告するため機能します。
QR ログインとアカウント復旧
QRコードログインは、パスワードの問題をスマートフォン側に移します。ユーザーが WeChat や DingTalk のアカウントを紛失した場合、スキャンできなくなります。これらのアイデンティティはいずれも Casdoor ユーザーにリンクされているだけであり、ユーザーそのものではないため、アプリケーションにメールまたは SMS プロバイダーがあり、ユーザーの住所が登録されていれば、検証コードでサインインしたり、パスワード再設定フローを通じてパスワードをリセットしたりできます。DingTalk と Lark はディレクトリから情報を補完しますが、WeChat ではサインアップ時に電話番号を要求してください。ページ上にこれら複数のオプションを表示するには、サインイン方法を参照してください。
参考資料
- DingTalk: ユーザートークン(
userAccessToken,expireIn7200)を取得: https://open.dingtalk.com/document/isvapp-server/obtain-user-token - DingTalk: 内部アプリのアクセストークンを取得: https://open.dingtalk.com/document/development/obtain-orgapp-token
- DingTalk: ユーザー個人情報を取得: https://open.dingtalk.com/document/orgapp-server/tutorial-obtaining-user-personal-information
- WeCom: access_token を取得: https://developer.work.weixin.qq.com/document/path/91039
- WeCom: Web ログインコンポーネント(
wwlogin/sso/login): https://developer.work.weixin.qq.com/document/path/98152 - WeCom: OAuth リンクとスコープを構築: https://developer.work.weixin.qq.com/document/path/91022
- WeCom: メンバーの機密情報を取得(
getuserdetail): https://developer.work.weixin.qq.com/document/path/95833 - WeCom: メンバーを読み取り(2022-06-20 フィールド変更): https://developer.work.weixin.qq.com/document/path/90196
- Feishu: user_access_token (v1) およびフィールド権限を取得: https://open.feishu.cn/document/server-docs/authentication-management/access-token/create-2
- WeChat: ウェブサイトアプリログイン: https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
- WeChat: UnionID: https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Authorized_Interface_Calling_UnionID.html
- Casdoor プロバイダー: https://github.com/casdoor/casdoor/tree/master/idp