Spring Boot AOP を用いた認可チェックの実装
1. 依存関係の追加(依存関係追加)
Spring Boot プロジェクトで AOP を使用するには、以下の依存関係を pom.xml
に追加します。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. カスタムアノテーションの作成(カスタムアノテーション作成)
まず、認可チェック用の @AuthCheck
アノテーションを作成します。
@Target(ElementType.METHOD) // メソッドに適用可能
@Retention(RetentionPolicy.RUNTIME) // 実行時に有効
public @interface AuthCheck {
/**
* 必須のユーザーロール(例: "ADMIN")
*/
String mustRole() default "";
}
このアノテーションを使うことで、特定のメソッドに「特定のロールが必要」という制約を簡単に追加できます。
3. AOP を使った認可インターセプターの実装(AOP インターセプター実装)
次に、@AuthCheck
アノテーションが付与されたメソッドを AOP を使ってインターセプトし、アクセス制御を行う AuthInterceptor
クラスを実装します。
@Aspect // AOP のアスペクトとして定義
@Component // Spring の Bean として管理
public class AuthInterceptor {
@Resource
private UserService userService;
/**
* 認可チェックのインターセプト処理
*
* @param joinPoint メソッド実行のコンテキスト
* @param authCheck 認可チェック用のカスタムアノテーション
* @return メソッドの実行結果
* @throws Throwable 例外処理
*/
@Around("@annotation(authCheck)")
public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
String mustRole = authCheck.mustRole(); // 必須のロールを取得
// HTTP リクエスト情報を取得
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
// 現在のログインユーザー情報を取得
User loginUser = userService.getLoginUser(request);
UserRoleEnum mustRoleEnum = UserRoleEnum.getEnumByValue(mustRole);
// 必須ロールが指定されていない場合、チェック不要なので通過
if (mustRoleEnum == null) {
return joinPoint.proceed();
}
// 現在のユーザーが持つロールを取得
UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(loginUser.getUserRole());
// ロール情報がない場合、認可エラー
if (userRoleEnum == null) {
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
}
// 必須ロールが ADMIN で、ユーザーが ADMIN でない場合はアクセス拒否
if (UserRoleEnum.ADMIN.equals(mustRoleEnum) && !UserRoleEnum.ADMIN.equals(userRoleEnum)) {
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
}
// 認可チェックを通過した場合、元のメソッドを実行
return joinPoint.proceed();
}
}
4. 認可チェックの適用(アノテーション適用)
作成した @AuthCheck
アノテーションを Controller
のメソッドに適用し、特定のロールが必要な API を実装します。
@RestController
@RequestMapping("/admin")
public class AdminController {
@Resource
private AdminService adminService;
/**
* 管理者専用 API
*/
@AuthCheck(mustRole = "ADMIN") // 管理者のみアクセス可能
@GetMapping("/dashboard")
public String getAdminDashboard() {
return adminService.getDashboardData();
}
}
このようにすることで、@AuthCheck(mustRole = "ADMIN")
を付けたメソッドは、「管理者ロール(ADMIN)を持つユーザーのみアクセス可能」というルールが適用されます。
5. まとめ(まとめ)
Spring AOP を活用して、カスタムアノテーションによる認可チェックを実装しました。これにより、認可ロジックを各メソッドに直接書く必要がなくなり、コードの再利用性が向上します。
本記事で学んだポイント
✅ @Aspect
を使って AOP クラスを定義
✅ @Around("@annotation(authCheck)")
でカスタムアノテーションをインターセプト
✅ HTTP リクエストから現在のユーザー情報を取得
✅ 必須のロールを満たしていない場合、例外をスローしてアクセス拒否
AOP を活用することで、認可チェックやロギング、パフォーマンス計測などの共通処理を簡単に適用できます。