2016-04-12 26 views
4

正しいタイトルを使用したかどうかはわかりませんが、より適切な記述方法を考えることができませんでした。それはもっと設計上の問題かもしれない。マルチテナントデータアクセスを使用したWeb API認証

1人のユーザーが1つ以上のエンティティに所属できるマルチテナントDBがあります。 /トークンエンドポイントを呼び出すことによって、ユーザーの資格情報でユーザーを認証します。

私はトークンを受け取った後、自分のエンドポイント(トークンを使用)を呼び出して、このユーザーの利用可能なエンティティのリストを取得し、このユーザーが現在のエンティティをメモリキャッシュに設定できるようにします。私はその後、メモリキャッシュでこれを使用して、DBを呼び出すときにユーザーがどのエンティティ/テナントに「ログインしているか」を知るためのすべての要求のエンティティ/テナントIDを検索します。

理想的には、エンティティ/テナントIDをトークンに含めることでアプリケーションをよりステートレスにするために、メモリキャッシュの必要性を排除したいと思いますが、ユーザーが認証されて選択された後でのみ彼/彼女の主体。私は明らかにトークンが発行された後、クレームを変更または追加することはできませんが、この種の動作を実装する代替設計がありますか?

私はおそらくテナントごとにサブドメインを使用していると考えましたが、技術的にはセットアップやメンテナンスが難しくなります。私はまた、ユーザーに資格情報を使って自由なテキストとしてログインしたいエンティティを入力するように促すことを考えましたが、これは理想的ではありません。

誰もこの挑戦に直面したことはありますか?

答えて

3

RESTベースのアーキテクチャでのステートフルな対話を避けるために、テナントの選択はステートレスな方法で行う必要があるという事実に同意します。キャッシュアプ​​ローチは、多くの落とし穴につながり、セッションベースの相互作用に強い依存関係を導入する可能性があります。私は2つの主要なオプションを考えることができ

はステートレステナント選択を行います:

  1. URIベースの選択:あなたはすべてのあなたのコントローラ間で共有テナントパラメータを、APIに追加できます。このようなマッピング:api/{tenantId}/{controller}/{id}を使用すると、簡単な方法でクライアント側でテナントを切り替えることができます。

    [RoutePrefix("api/{tenantId}/myentities")] 
    public class EntityController : ApiController 
    { 
        [Route("")] 
        public IHttpActionResult GetAllEntities(string tenantId) 
        { 
         //... 
    
  2. ヘッダーは、ベースの選択:あなたは追加することを検討可能性があり、あなたのコントローラ上RoutePrefixAttributeを使用して、

    routes.MapHttpRoute(
        name: "API Default", 
        routeTemplate: "api/{tenantId}/{controller}/{id}", 
        defaults: new { id = RouteParameter.Optional } 
    ); 
    

    または属性ベースのルーティング:これは規則ベースのルーティングの両方を使用して行うことができます選択されたテナントに関する情報を含むカスタムHTTPヘッダーX-Tenant-Selection: TenantIdであれば、このヘッダーinside a custom Filter、またはWeb APIより前に実行されたOwinMiddlewareを読み込み、コントローラ内でコンテキスト変数(または現在の要求のために持続するユーザークレーム)を設定することができます。

もちろん両方のシナリオで、データを返す前に現在のユーザーが選択したテナントにアクセスできることを検証する必要があります。

率直に言えば、アクセストークンの内部にtenantIdを含めることはできませんが、サブドメインのアプローチはあまりにも複雑です。

+0

あなたの回答Federicoに感謝します。これはまさに私が後にしたものです。 – Ross

+2

_ ** "アクセストークンの内部にテナントIDを含めることはできません" ** _ - 私は同意します。アクセストークンは、リクエスト自体ではなく、リクエスタのプロパティを識別するためのものでなければなりません。私。彼らが何をすることができるのかを示しています。 2つのシナリオを混在させることが問題となるのは、ユーザーが複数のテナントにアクセスし、トークンに複数のテナントIDが含まれている可能性があるということです。 – Snixtor

+1

アクセストークンにTenantIdを含めることが維持しやすくなるとは思わないでしょうか。フロントエンドの人はトークン全体を送信するだけで、データはアクセストークンに基づいてフィルタリングされますか? –

関連する問題