0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Spring AOP With Annotation

Posted at

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 を活用することで、認可チェックやロギング、パフォーマンス計測などの共通処理を簡単に適用できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?