IPアドレスによるアクセス制限とは
業務系Webアプリケーション構築時には、「特定のIPアドレスからのアクセスのみ許容したい」といった要件はありがちかと思います。
通常、インフラ側で制御すれば良い話ではあり、AWSであれば下記の方法で設定可能です。
- ALBのリスナールール
- ネットワークACL
- セキュリティグループ
Webアプリケーション側で実装する必要性
前項の通り、AWSで設定することにより、簡単に実施できます。
しかし、下記のケースではどうでしょうか。
- ユーザーが二種類ある(user, admin)
- adminの中でも権限が分かれている
- adminの特定の権限のみIPアドレスによるアクセス制限を実施したい
「adminのみIPアドレスを制限したい」ということであれば、ALBのリスナールールでパス指定することにより、なんとかなりそうです。
厄介なのが、「adminの特定の権限のみ」という部分です。ログイン認証後しか判定できないため、Webアプリケーション側で実施する必要があります。
実装方法
MiddleWareを使って実装していきます。
MiddleWare作成
App\Http\Middleware\IpRestrictionMiddleware.php
を作成します。
class IpRestrictionMiddleware
{
public function handle($request, Closure $next){
//開発環境以外 && 権限チェック
if(config('app.env') !== 'local' && Auth::guard('admin')->check() && Auth::user()->role === Admin::ROLE_RESTRICTION){
//IPアドレストを比較
if(in_array($request->ip(), Admin::IP_ADDRESS_LIST) === false){
Auth::guard('admin')->logout();
abort(404);
}
}
return $next($request);
}
}
config('app.env') !== 'local
の判定を入れることで、開発環境ではアクセス制限を無効化できます。
今回は、Admin::ROLE_RESTRICTION
にアクセス制限をする権限を記載している体ですが、フラグ的なカラムの追加や、判定式にハードコーディングでもOKです。
同じく、Admin::IP_ADDRESS_LIST
にアクセス可能なIPアドレスを記載している体ですが、IpRestrictionMiddleware
に記載、IPアドレス自体をテーブルに保持してもOKです。
ただし、テーブルに保持した場合は、MiddleWareを通過する毎にDBへのアクセスが発生するため注意してください。
アクセス制限をする権限で、IPアドレスが異なる場合には、ログアウト実施後に404が表示されます。
404ではなく、別画面に誘導したい場合には、return to_route(xxx)
を記載してください。(Laravelのバージョンにより記載の差異あり)
Kernel.phpへ記載
App\Http\Kernel.php
に先ほど作成したMiddleWareを追記します。
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
#...
'ip.restriction' => \App\Http\Middleware\IpRestrictionMiddleware::class, #追記
];
上記を追記することで、web.php
に記載する準備が整います。
web.php
web.php
のMiddleWareを実行させたい箇所に記述をしていきます。
# 配下に一括で適用
Route::group(['prefix' => 'admin', 'middleware' => ['ip.restriction']], function () {
#...
});
# 個別で適用
Route::get('/hoge',[App\Http\Controllers\Admin\HogeController::class, 'index'])->name('admin.hoge')->middleware('ip.restriction');
実装は以上になります。
まとめ
MiddleWareを使うことで既存のWebアプリケーションにも簡単にアクセス制限を追加できます。
記述の仕方や実現方法は様々あるかと思いますので、参考程度に見て頂けると幸いです。
最後までお付き合いいただき、ありがとうございました。