4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Spring SecurityのPreAuthorizeで独自メソッドを呼び出す

Posted at

Spring Securityのメソッド認可でちょっと複雑なロジックで認可したい場合、任意のbeanのメソッドを呼び出すことが出来ます。

ちなみにカスタム認証を正しく追加したい場合は PermissionEvaluator を実装するのが恐らく正当なアプローチです。
PermissionEvaluatorの実装についてはこちらの記事が分かりやすく詳しかったです。
拡張フレームワーク開発などで汎用的なEvaluatorを追加したい場合はこちらがよいでしょう。
https://www.codeflow.site/ja/article/spring-security-create-new-custom-security-expression

今回はもうちょっとお手軽な方法でも書けるよという手順です。

Controller側のPreAuthorize定義

Controller.java
    @PreAuthorize("@customPreAuthorizer.belongGroup(#groupId, authentication.principal)")
    @RequestMapping("/group/{groupId}/list")
    public String list(Model model, @PathVariable("groupId") Long groupId) {
    }

Bean定義

CustomPreAuthorizer.java
@Component
public class CustomPreAuthorizer {
    public boolean belongGroup(Long groupId, UserDetails userDetails) {
         // ここで独自認可を実装。実行を許可する場合にtrueを返す。
        return true;
    }
}

解説

PreAuthorizeのexpression内でBean名の先頭に@をつけることで、コンポーネント登録されたBeanを参照出来ます。
@customPreAuthorizer

認証ユーザのユーザ情報はauthentication.principalで引数に渡すことが出来ます。

PreAuthorizeで引数に渡すのが記述として冗長であれば、メソッド内でSecurityContextを呼んでも同じものが取得できるので、メソッド内で取り出すことも可能です。

CustomPreAuthorizer.java
@Component
public class CustomPreAuthorizer {
    public boolean belongGroup(Long groupId) {
        var userDetails = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        return true;
    }
}

あとはUserDetailsを拡張して必要な情報をログイン時に持たせておけば、拡張した独自認可を実装して提供できます。

4
5
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
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?