先日、Laravel 5.3 で Passportを試す | ぴんくいろにっきという記事にLaravel 5.3 で使えるようになった公式パッケージである Passport で OAuth2を使う方法とかを書いたわけですが、この際に気になったこととしてデフォルトで全ての認証方法(パーソナルアクセストークン含む)が利用できるといった懸念点がありました。
そこで、これを解決する手段を探してみました。
使用できるgrant_typeを制限したい
Passportでは \League\OAuth2\Server\AuthorizationServer
の$enabledGrantTypes
に\Laravel\Passport\PassportServiceProvider::registerAuthorizationServer
で各grantTypeを登録しています。これを制御すれば有効化するgrantTypeを絞れるのでは、と思ったものの、当該メソッドが軒並みprotectedだったのでなんだか面倒そう。(言い換えれば、\Laravel\Passport\PassportServiceProvider
を継承するProviderを作ってregisterAuthorizationServerをオーバーライドし、このクラスでconfigの該当箇所とかを置き換えれば十分用がたせそうな気がしますね、書いてから気付いた。)
パーソナルアクセストークンは要らないけれど、それ以外の各種は使いたいので少しやるたいことと違う気もします。
パーソナルアクセストークン、grant_type:passwordはいらない
検証できてなくてアレだけど personal_access_client, password_client のそれぞれを持つクライアントがなければいいはず(?)
とはいえこれだけではパーソナルアクセストークン取得のエンドポイントは残るので少し気持ち悪い。
利用できるAPIエンドポイントを絞る
セットアップガイドに沿って進めている場合、Passport::routes()
をapp/Providers/AuthServiceProvider.php
に追加していると思いますが、このメソッドは実は第一引数にクロージャでコールバックを取ります。
指定がなかった場合のデフォルトコールバックは
function ($router) {
$router->all();
}
で、引数に渡ってくるrouterは\Laravel\Passport\RouteRegistrar
、すなわち $router->all()
は
public function all()
{
$this->forAuthorization();
$this->forAccessTokens();
$this->forTransientTokens();
$this->forClients();
$this->forPersonalAccessTokens();
}
となっています。
例えば「パーソナルアクセストークンは不要、普段はパスワード認証を用いるが管理者側から生成したcode認可のクライアントも使用できるようにする」といった場合、AuthServiceProviderには
Passport::routes(function (RouteRegistrar $router) {
// /oauth/tokens
$router->forAccessTokens();
// /oauth/authorization
$router->forAuthorization();
});
としておけばこの条件が満たせるルーティングになります。
必要に応じてこれを1つ目、2つ目の方法と併用されることをおすすめします。
Passport、便利なんだけどドキュメントがあまり充実していなくて日本語資料も全然見当たらなくてつらい。
もし戉や「こここうした方がいいよ」等指摘があればコメントでどんどん投げていただければと思います。