Spring Boot / 認証 / スクラッチ

Spring Boot / 認証 / スクラッチ

Spring Security による実用レベルの認証実装がかなりめんどくさいアンド理解できそうにもないので、実用レベルの実装をスクラッチで作ってみる。

認証にはいくつの機能で構成されていると思うのでこれを1つづつ実装していきたい。

  • 共通的にページをガードしてアクセス不能にする 403 出す
  • しかるべきページ(ログインページ)等に飛ばす
  • 一部のページだけ許可する
  • ログインフォームを表示する
  • ログイン状態を維持する
  • ログイン情報を引き出す
  • ロール別挙動変化
  • ログアウトする

とりあえずこのぐらいの話になる。

実際やってみたのは Spring Boot / 認証 / スクラッチ / HelloWorld ココ

やってみた感想としてはどの機能もかなり簡単に実装できる。 Spring Security に頼る必要などまったく無いと思えるぐらい簡単。

共通処理

Spring Boot の Web において Controller に共通処理を入れ込むには何をすればいいのか?

Spring Boot/Controller/共通処理/Interceptor ここ参照。

interceptor を使って入れ込む

ガードする

interceptor によって false を返すと処理がそこで終了できる。これによりページをガードできる。

一部のページだけ許可する

ざっくり

Spring Boot/Controller/共通処理/Interceptor ここを参照。

interceptor の登録時に exclude 指定できるのでそれでOK

個別に

つけ忘れでガードが外れるのが嫌なので基本全ガードで アノテーションをつけたモノだけガードから外すというものを作る。

なのでアノテーションを作る。

package com.example.demo.annotation;
 
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType;
 
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface NoAuth {
}

こいつを許可したい Controller のメソッドに取り付ける

@Controller
@RequestMapping("/hoge")
public class HogeController {
    @NoAuth
    @RequestMapping("")
    public String index() {
        return "hoge/index";
    }
}

これだけでは印がついただけなのでこの印に対して処理を書く。 当然それは interceptor の中で書く。

interceptor のハンドラのシグネチャはこうなっていて

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

この handler というモノからその呼び出されているメソッド情報を取り出すことができる。 そのメソッド情報からアノテーションの有無を判断する。

HandlerMethod h = (HandlerMethod) handler;
Method m = h.getMethod();
NoAuth a = AnnotationUtils.findAnnotation(m, NoAuth.class);
if(a != null){
}

これにより interceptor の結果を変えれば個別対処できるようになる。

ログインフォームを表示する

これは特に特別なことはない。単に controller を作って HTML を出力すればいい。

ログイン処理をする

ログインフォームからの値を検証して、その結果をセッションに詰めておくことでログイン状態とすることにする。

セッションの張替え

これは HttpSession を直接扱えばよいようだ。Controller に対しては Autowired で入れてくれるそうなので基底クラスに実装して必要な Controller で呼び出せばいける。

セッションにユーザー情報を保持する

Controller を跨ってセッションに情報を保持するには、

対象のクラスを セッションスコープBean というモノとして登録して、そいつを各 Controller で Autowired すれば毎度復帰するようだ。

java/spring/spring_boot/auth/scratch/start.txt · 最終更新: 2021-05-12 16:55 by ore