付録A 主要ライブラリ・フレームワークの比較
A.1 認証ライブラリの比較
A.1.1 Node.js/JavaScript
ライブラリ | 特徴 | 適用場面 | 注意点 |
---|---|---|---|
Passport.js | - 500+の認証戦略 - 柔軟なミドルウェア設計 - 大規模コミュニティ |
- Express/Koa等のNode.jsアプリ - 多様な認証方式が必要な場合 |
- セッション管理は別途必要 - TypeScript型定義が不完全 |
Auth0 SDK | - マネージドサービス - 豊富な機能 - 優れたドキュメント |
- 迅速な開発が必要 - エンタープライズ要件 |
- ベンダーロックイン - コスト(MAU課金) |
NextAuth.js | - Next.js最適化 - OAuth統合が簡単 - TypeScript完全対応 |
- Next.jsプロジェクト - JAMstack架構 |
- Next.js以外では使いづらい - カスタマイズに限界 |
node-oidc-provider | - OpenID Connect準拠 - 高度なカスタマイズ可能 - 認定実装 |
- OIDCプロバイダー構築 - 標準準拠が必須 |
- 学習曲線が急 - 設定が複雑 |
実装例:Passport.js
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const JwtStrategy = require('passport-jwt').Strategy;
// ローカル認証戦略
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
async (email, password, done) => {
try {
const user = await User.findOne({ email });
if (!user || !await user.validatePassword(password)) {
return done(null, false, { message: 'Invalid credentials' });
}
return done(null, user);
} catch (error) {
return done(error);
}
}
));
// JWT認証戦略
passport.use(new JwtStrategy({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET
},
async (payload, done) => {
try {
const user = await User.findById(payload.sub);
return done(null, user || false);
} catch (error) {
return done(error, false);
}
}
));
A.1.2 Python
ライブラリ | 特徴 | 適用場面 | 注意点 |
---|---|---|---|
Django-Allauth | - Django統合 - ソーシャル認証対応 - 管理画面付き |
- Djangoプロジェクト - 迅速な開発 |
- Django依存 - カスタマイズが複雑 |
FastAPI-Users | - 非同期対応 - 型安全 - モダンな設計 |
- FastAPIプロジェクト - 高性能API |
- 比較的新しい - エコシステムが発展途上 |
Authlib | - OAuth/OIDC完全実装 - フレームワーク非依存 - 高品質コード |
- 複雑な認証要件 - 標準準拠重視 |
- 低レベルAPI - ドキュメントが技術的 |
python-jose | - JWT処理特化 - 暗号ライブラリ選択可 - 軽量 |
- JWT認証のみ - マイクロサービス |
- 認証フローは自前実装 - セキュリティ設定に注意 |
実装例:FastAPI-Users
from fastapi import FastAPI, Depends
from fastapi_users import FastAPIUsers, BaseUserManager
from fastapi_users.authentication import JWTStrategy
from fastapi_users.db import SQLAlchemyUserDatabase
class UserManager(BaseUserManager[UserCreate, UserDB]):
async def on_after_register(self, user: UserDB, request=None):
# 登録後の処理
await send_welcome_email(user.email)
async def on_after_login(self, user: UserDB, request=None):
# ログイン後の処理
await log_login_event(user.id, request)
def get_jwt_strategy() -> JWTStrategy:
return JWTStrategy(
secret=settings.JWT_SECRET,
lifetime_seconds=3600,
token_audience=["fastapi-users:auth"]
)
fastapi_users = FastAPIUsers(
get_user_manager,
[auth_backend],
UserModel,
UserCreateModel,
UserUpdateModel,
UserDB,
)
app = FastAPI()
app.include_router(
fastapi_users.get_auth_router(auth_backend),
prefix="/auth",
tags=["auth"]
)
A.1.3 Java
ライブラリ | 特徴 | 適用場面 | 注意点 |
---|---|---|---|
Spring Security | - 包括的セキュリティ - Spring統合 - エンタープライズ標準 |
- Springアプリケーション - 複雑な要件 |
- 設定が複雑 - 学習コスト高 |
Apache Shiro | - シンプルAPI - フレームワーク非依存 - セッション管理込み |
- 軽量な実装 - レガシーシステム |
- 機能が限定的 - コミュニティ縮小 |
Keycloak Adapter | - Keycloak連携 - 多様なプロトコル - 設定のみで動作 |
- Keycloak使用時 - SSO要件 |
- Keycloak依存 - オーバーヘッド |
Pac4j | - 多プロトコル対応 - フレームワーク中立 - 軽量 |
- 複数認証方式 - マイクロサービス |
- ドキュメント不足 - 日本語情報少 |
実装例:Spring Security
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.oauth2Login(oauth2 -> oauth2
.userInfoEndpoint(userInfo -> userInfo
.userService(customOAuth2UserService())
)
)
.jwt(jwt -> jwt
.decoder(jwtDecoder())
)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.build();
}
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withPublicKey(publicKey()).build();
}
}
A.2 IDプロバイダー/SaaSの比較
A.2.1 商用サービス
サービス | 特徴 | 価格帯 | 適用場面 |
---|---|---|---|
Auth0 | - 開発者フレンドリー - 豊富な統合 - グローバル展開 |
7,000 MAU無料 $23~/月 |
- スタートアップ - B2C向け - 迅速な開発 |
Okta | - エンタープライズ向け - 高度な管理機能 - コンプライアンス対応 |
要見積もり $2~/user/月 |
- 大企業 - B2B/B2E - 規制業界 |
AWS Cognito | - AWS統合 - サーバーレス対応 - 従量課金 |
50,000 MAU無料 $0.0055/MAU |
- AWSユーザー - コスト重視 - シンプル要件 |
Firebase Auth | - Google統合 - リアルタイムDB連携 - モバイル最適化 |
無料枠大 $0.06/認証 |
- モバイルアプリ - Google生態系 - プロトタイプ |
Azure AD B2C | - Microsoft統合 - エンタープライズ機能 - ハイブリッドID |
50,000 MAU無料 $0.00325/MAU |
- Microsoft環境 - ハイブリッドクラウド |
A.2.2 オープンソース
プロダクト | 特徴 | 運用難易度 | 適用場面 |
---|---|---|---|
Keycloak | - Red Hat支援 - 完全機能 - 管理UI充実 |
中 | - オンプレミス要件 - カスタマイズ必要 - エンタープライズ |
Ory | - クラウドネイティブ - マイクロサービス - API中心 |
高 | - Kubernetes環境 - 高度なカスタマイズ - 開発者向け |
Authelia | - リバースプロキシ統合 - 2FA対応 - シンプル |
低 | - ホームラボ - 小規模環境 - Traefik/nginx利用 |
Zitadel | - イベントソーシング - マルチテナント - SaaS版あり |
中 | - B2B SaaS - イベント駆動 - 監査重視 |
A.3 パスワードハッシュライブラリ
A.3.1 推奨アルゴリズムと実装
アルゴリズム | ライブラリ | 特徴 | 推奨設定 |
---|---|---|---|
Argon2 | argon2-cffi (Python) argon2 (Node.js) Spring Security |
- 最新標準 - メモリハード - 並列化可能 |
memory: 64MB iterations: 3 parallelism: 2 |
bcrypt | bcrypt (各言語) 広くサポート |
- 実績豊富 - 広範なサポート - 固定メモリ |
cost factor: 12 (2024年基準) |
scrypt | scrypt (Node.js) hashlib (Python) |
- メモリハード - ASIC耐性 - 調整可能 |
N: 16384 r: 8 p: 1 |
PBKDF2 | 標準ライブラリ 全言語対応 |
- 標準化 - 軽量 - FIPS認証 |
iterations: 600,000 SHA-256 |
実装例:Argon2
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
class SecurePasswordManager:
def __init__(self):
self.ph = PasswordHasher(
memory_cost=65536, # 64 MB
time_cost=3, # 3 iterations
parallelism=2, # 2 parallel threads
hash_len=32, # 32 bytes
salt_len=16 # 16 bytes
)
def hash_password(self, password: str) -> str:
"""パスワードをハッシュ化"""
return self.ph.hash(password)
def verify_password(self, password: str, hash: str) -> bool:
"""パスワードを検証"""
try:
self.ph.verify(hash, password)
# 必要に応じてrehash
if self.ph.check_needs_rehash(hash):
return True, self.ph.hash(password)
return True, None
except VerifyMismatchError:
return False, None
A.4 JWT/セッション管理ライブラリ
A.4.1 JWT実装の比較
言語 | ライブラリ | 特徴 | 注意点 |
---|---|---|---|
JavaScript | jsonwebtoken jose |
標準実装 最新仕様対応 |
algorithm指定必須 JWK対応 |
Python | PyJWT python-jose |
シンプル 高機能 |
暗号ライブラリ選択 依存関係多 |
Java | Nimbus JOSE jjwt |
完全実装 Android対応 |
サイズ大 設定複雑 |
Go | golang-jwt jose2go |
高性能 標準準拠 |
APIが低レベル v3/v4で破壊的変更 |
セキュアな実装例
const jwt = require('jsonwebtoken');
const jwksRsa = require('jwks-rsa');
class JWTManager {
constructor() {
// 公開鍵の動的取得
this.jwksClient = jwksRsa({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: process.env.JWKS_URI
});
}
async signToken(payload, options = {}) {
const defaultOptions = {
algorithm: 'RS256',
expiresIn: '1h',
issuer: process.env.JWT_ISSUER,
audience: process.env.JWT_AUDIENCE,
keyid: process.env.JWT_KEY_ID
};
return jwt.sign(
payload,
process.env.JWT_PRIVATE_KEY,
{ ...defaultOptions, ...options }
);
}
async verifyToken(token) {
const getKey = (header, callback) => {
this.jwksClient.getSigningKey(header.kid, (err, key) => {
if (err) return callback(err);
const signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
};
return new Promise((resolve, reject) => {
jwt.verify(token, getKey, {
algorithms: ['RS256'],
issuer: process.env.JWT_ISSUER,
audience: process.env.JWT_AUDIENCE
}, (err, decoded) => {
if (err) reject(err);
else resolve(decoded);
});
});
}
}
A.5 WebAuthn/FIDO2実装
ライブラリ | 言語 | 特徴 | 実装難易度 |
---|---|---|---|
SimpleWebAuthn | TypeScript/JS | - 使いやすいAPI - 充実したドキュメント |
低 |
py_webauthn | Python | - Python標準 - 型アノテーション対応 |
中 |
WebAuthn4J | Java | - Spring統合 - 詳細な検証 |
高 |
go-webauthn | Go | - Duoメンテナンス - 高性能 |
中 |
実装例:SimpleWebAuthn
import {
generateRegistrationOptions,
verifyRegistrationResponse,
generateAuthenticationOptions,
verifyAuthenticationResponse
} from '@simplewebauthn/server';
class WebAuthnService {
async startRegistration(user: User) {
const options = generateRegistrationOptions({
rpName: 'Example Corp',
rpID: 'example.com',
userID: user.id,
userName: user.email,
userDisplayName: user.name,
attestationType: 'indirect',
authenticatorSelection: {
authenticatorAttachment: 'platform',
userVerification: 'required'
}
});
// チャレンジを保存
await this.saveChallenge(user.id, options.challenge);
return options;
}
async completeRegistration(
user: User,
credential: RegistrationCredentialJSON
) {
const expectedChallenge = await this.getChallenge(user.id);
const verification = await verifyRegistrationResponse({
credential,
expectedChallenge,
expectedOrigin: 'https://example.com',
expectedRPID: 'example.com',
requireUserVerification: true
});
if (verification.verified) {
await this.saveCredential(user.id, {
credentialID: verification.registrationInfo.credentialID,
publicKey: verification.registrationInfo.credentialPublicKey,
counter: verification.registrationInfo.counter
});
}
return verification.verified;
}
}
A.6 選定のためのチェックリスト
技術選定時の評価項目
security_requirements:
- [ ] 暗号アルゴリズムの最新性
- [ ] 既知の脆弱性の有無
- [ ] セキュリティアップデートの頻度
- [ ] デフォルト設定の安全性
compatibility:
- [ ] 対象プラットフォームのサポート
- [ ] 既存システムとの統合容易性
- [ ] 標準規格への準拠度
- [ ] バージョン互換性
performance:
- [ ] ベンチマーク結果
- [ ] メモリ使用量
- [ ] レスポンスタイム
- [ ] スケーラビリティ
maintainability:
- [ ] ドキュメントの充実度
- [ ] コミュニティの活発さ
- [ ] 商用サポートの有無
- [ ] ライセンスの適合性
cost:
- [ ] 初期導入コスト
- [ ] ランニングコスト
- [ ] 隠れたコスト(運用・教育)
- [ ] スケール時のコスト予測
推奨構成例
小規模アプリケーション(〜1万ユーザー)
- 認証: NextAuth.js or Django-Allauth
- パスワード: bcrypt (cost=12)
- セッション: JWTまたはCookieセッション
- MFA: TOTP (Google Authenticator互換)
中規模SaaS(〜10万ユーザー)
- 認証: Auth0 or AWS Cognito
- パスワード: Argon2id
- セッション: JWT + Refresh Token
- MFA: WebAuthn + TOTP fallback
エンタープライズ(10万ユーザー〜)
- 認証: Okta or Keycloak
- パスワード: 段階的にパスワードレスへ
- セッション: Distributed session with Redis
- MFA: WebAuthn + 複数バックアップ方式