#はじめに
Jiraには外からデータにアクセスするためのAPIが用意されています。最新の仕様はここにありますが、通常のGUIを介することなく課題のリストを取得したり、各々の課題の詳細を得たりそれらを改変したりができます。Jiraそれ自体もかなり強力なツールですが、APIを利用することで他のツールと連携させてより便利に利用するという可能性が広がります。
利用されている方はご存知のように、Jiraにはアカウントの概念があり通常はログインを行って利用することになります。そしてアカウントごとに閲覧できるプロジェクトや行える操作を細かく設定することができます。APIを利用する際も同様でまずはユーザ認証を行ってから利用することになります。一番簡単な方法は、HTTPのBasic認証を使ってユーザ名とパスワードを直接APIに渡す方法ですが、WebサービスからAPIを利用する場合にはこれでは不都合があるため、OAuthという方法を使って認証・認可を行います。本稿ではその仕組みと実現方法をステップバイステップで紹介したいと思います。
#OAuthとは
OAuthは「認可(Authorization)」を行うための標準仕様です。認証(Authentication)となにが違うのか混乱しがちですが、一言で言うと、認証は「あなたがあなたであることを確認する(本人認証)」で、認可は「他の誰かにあなたの持ち物を使うことを許すこと(権限委譲)」です。
認可に比べて認証はわかりやすく、いわゆる「ログイン」のことです。これまではユーザ名とパスワードによって行うことが多かったですが、最近では指紋や静脈をつかったり、最新のiPhoneでは顔を見せることで本人確認できるようになっています。では認可とはなにか?
その説明のためにまずはじめに通常のJiraのアクセスを考えてみます。GUIであろうがAPIであろうが、ユーザはJiraに対してユーザ名・パスワードを渡してユーザ認証を行いJiraに格納されたデータにアクセスします。ここでは認証はありますが認可は必要ありません。
次にJiraのデータにアクセスして加工して表示するWebサービスを考えてみます。通常のアクセスの場合と同じように考えると、Webサービスに対してユーザ名・パスワードを渡し、Webサービスがそれを使ってJiraにアクセスし情報を取ってきて、それを加工して返すという形が考えられます。
ただこのやり方には問題があります。というのも、Webサービスに一度ユーザ名とパスワードを渡してしまうとそのWebサービスはいつでもどこでもそのアカウントの情報を取り放題ということになります。さらにパスワードを変えることすらでき、アカウントを乗っ取ってしまうこともできます。ほとんどのWebサービスがそんな悪意をもったサービスではないと思いますが、パスワードを第三者に渡すというのはやはり気持ち悪い。そこでOAuthと認可の考えが登場します。
OAuthではパスワードを渡すのはあくまでもデータを持っている側のサービスでこの場合はJiraになります。Jiraはユーザ認証したのちに「このサービスにデータを渡すけど良い?」と確認した後にトークンを発行します。これが認可の作業。Webサービスはそのトークンを使ってデータにアクセスできるというわけです。トークンには有効期限があるのでずっとアクセス権を与えっぱなしということにはならないですし、さらに必要であればいつでもJiraの側からそのトークンの無効化もできます。
なお、OAuthには1.0(a)と2.0の二つのバージョンがあります。基本的な認可の考え方は同じですが、技術的なアプローチが異なり互換性がありません。私はこれまで2.0しか扱ったことがなかったのですが、JiraのAPIは1.0aで実装されていて今回初めて使ってみました。
#OAuthを使うための準備
JiraでOAuthを使うにはいくつかの準備が必要になります。
- 非対称鍵ペアの作成
- Jiraの設定変更
非対称鍵ペアの作成
お使いのシステムでopenssl
がインストールされていると仮定し、以下のコマンドで生成できます。一つ目でRSAの鍵ペアを生成し、二つ目で公開鍵の方を別ファイルに書き出しています。
$ openssl genrsa -out jira.pem 1024
$ openssl rsa -in jira.pem -pubout -out jira.pub
Jiraの設定変更
設定変更にはJiraのAdmin権限が必要です。そして次のようにしてアプリケーションリンクを作成します。
- Jiraの設定 → アプリケーション → アプリケーションのリンクを開く
これで準備は完了です。
#JiraのOAuth認可 ステップバイステップ
今回、OAuthの挙動を確認するためにサンプルのWebアプリケーション(qatlassian)をPython+Flaskで作ってみました。それを用いてどのようなステップで認証・認可が進むのかを説明したいと思います。なお、アプリのソースコードはこちらにあります。
基本的な流れは以下の通り。
- qatlassianがJiraからリクエストトークンの取得し、認証・認可のURLを作ってブラウザに返す
- ブラウザは返されたURLにリダイレクトされ(リダイレクト先はJira)、そこでユーザ名・パスワードを入力。qatlassianにデータを渡して良いかの確認(認可)をおこなう。
- ブラウザは再びqatlassianにリダイレクトされ、qatlassianはアクセストークンをJiraから取得
- qatlassianはアクセストークンを用いてJiraのデータへアクセス
ここで一つ気をつけなければならないのは、Jiraから返されたアクセストークンはユーザに結びつけられた情報なのでセッションごとに保持しなければならないということ。アプリレベルで保持してしまうとログインしていないユーザは他のユーザの権限でJiraにアクセスしたりということが起きてしまいます。
これを見ると複雑なステップに見えますが、自動的にリダイレクトされたりして進むのでブラウザの前に座るユーザ的にはそれほど複雑でもないです。ユーザ視点ではこんな感じ。なお、テストのためにqatlassianはローカル環境で動かしています。
- 初期状態で
http://localhost:5000/
にアクセスするとloginへのリンクが表示されます。
- それをクリックすると少し待たされますが次に表示されるのはJiraのログイン画面 (実際にはAtlassian共通のログインですが)
- ユーザ名・パスワードを入れてログインすると次に認可確認の画面が表示されます。
- それで許可をするとまた少し待たされますが、qatlassianがJIRAから取得したデータを表示します(このサンプルではユーザの emailアドレスとアクセス権のあるプロジェクトの課題のリスト)
別のブラウザからアクセスすると毎回ログインを促されますし、別のアカウントでログインするとその権限の違いによって取れるデータにも違いがあるのがわかります。ここでは以下のような権限設定を行なっています。
アカウント | PROJ | RED | BLUE |
---|---|---|---|
qiita.atlassian@gmail.com | OK | OK | OK |
qiita.atlassian+1@gmail.com | OK | OK | NG |
qiita.atlassian+2@gmail.com | OK | NG | OK |
なお動作させるには.env
ファイルに以下の環境変数を設定してください。
変数 | 値 |
---|---|
JIRA_SERVE_URL | 利用するJIRAサーバのURL |
CONSUMER_KEY | 上記のセットアップ時に設定したコンシューマーキー |
PRIVATE_KEY | 上記で生成したプライベート鍵(jira.pemの中身) |
SECRET_KEY | なんでも良いです。Sessionを利用するために必要です |
#最後に
最新版のAPIでは2.0もサポートしているようなので、機会があれば今後そちらも試してみたいと思います。