thirose’s blog

openstackやpythonなどなど

keystoneの複数の認証メソッドが絡んだ認証の問題とその解決

概要

keystoneの複数の認証方法がある環境でおこった、一部ユーザがログインできなくなる問題がありました。 今回の記事ではkeystoneの認証の流れと、その中でおこった今回の問題の原因への対応をまとめました。

keystone

Keystoneとは、OpenStackの認証やユーザ・プロジェクト・ロールなどの管理を行っているコンポンポーネントです。今回はその認証部分についてまとめてあります。

keystoneの認証メソッド

まずはどのような認証メソッドがあるのかというと、以下の3種類が標準の認証メソッドになります。

  • password
    • ユーザIDとパスワードによる認証
  • token
    • tokenを利用した認証
  • external
    • 外部認証によって使われる場合に使われる認証

また、これらに加えSSOによる認証でmappedを追加しています。

今簡単に説明した認証メソッド4つをkeystone.confに設定された状態(下記サンプル)でおきた認証エラーについてまとめています。

[auth]
methods = external, password, token, mapped

どのような問題がおきたのか

普段認証にはSSOを使用し、SSOを導入する前まではpasswordによる認証が使われていました。そのため、ユニークキーとしてはIDがあれば問題ありませんでした。 しかし、そこに検証でメールアドレスを追加してしまってたため、普段つかわれても問題なかったexternalに後から検証で登録されたユーザで 認証をしようとしてしまっていることで認証ができなくなっていました。

原因の把握

まず、この問題を認識した時に、確認したのは特定の(idにメールアドレスが登録された)ユーザがログインできないこと、かつpassword認証ではログインできたことを確認しました。 しかし、SSOを使った認証は認証エラーになってしまっている状態ということを確認。
続いてSSOのデータはどうか。Mellonを使い、idPと通信しkeystoneの認証情報とのmappingのためのデータをしっかり渡せているのか、どのフェーズでのエラーなのか、という確認をしました。
そこで判明したことは、まずデータのmappingのところまではしっかりデータを渡せているが、その後の処理でエラーがおきていました。

該当エラーについて

    def build_local_user_context(auth_context, mapped_properties):
        user_info = auth_plugins.UserAuthInfo.create(mapped_properties,
                                                     METHOD_NAME)
        auth_context['user_id'] = user_info.user_id

参照元: keystone/mapped.py at mitaka-eol · openstack/keystone · GitHub

mapped pluginの build_local_user_context メソッドの

auth_context['user_id'] = user_info.user_id

この行に問題があることがわかりました。まず、user_info.user_idにはmappedで評価される正しいログイン情報が入ってることが確認されました。 しかし、auth_context['user_id'] には別の(idにメールアドレスが登録され、メールアドレスが正しいユーザと重複されている)ユーザ情報が保持されてました。さらに auth_contextは frozonsetでセットされているため、該当の行で例外が発生していました。

参照元: keystone/core.py at d97832e8e826e37171b727072c720a9b589998dd · openstack/keystone · GitHub

解決方法

考えられる対応策は2つになります。そこで今回は2を選び対応をしました。 1も当初検討しましたが、本当にexternalメソッドが必要になったときにとても困ります。 また、externalは使用していなかったので削除し、ログインができることを確認しました。

  1. idPから渡されるREMOTE_USERを修正
  2. external メソッドをconfigから消す