|
ログインしないURL直アクセスの防止
業務アプリケーションではほとんどの場合、ログイン画面でユーザー認証を行い、メインメニューから各画面に遷移します。
ログインせずにURL直打ちで各画面が利用できてしまうと認証の意味がないので、
意図しないアクセスは事前にトラップして「ログインしていません」エラーページに遷移するか、
黙ってログイン画面に遷移するかを行うと思います。ここでは独自のエラーページに遷移する例で説明します。
[1] Interceptorクラスの作成
インターフェース HandlerInterceptor を実装するクラスを作成し、preHandleメソッドをオーバーライドします。
この処理で防止すべきアクセスを見つけたらエラーのURLに遷移してfalseを返します。
エラーURLはここでは /denied としていますが、自由に決められます。
一方、正当なアクセスとして要求を通過させたい場合はtrueを返すように作ります。
import org.springframework.web.servlet.HandlerInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if(request.getSession().getAttribute("LoginUserId") == null) {
// ログイン情報がない…エラーページに飛ぶ
response.sendRedirect("denied");
return false; // アクセスされたControllerには到達させない意味
}
return true; // 処理を許可
}
}
|
[2] Interceptor登録処理クラスを作る
Interceptor が効くようにアプリケーションに登録する処理は、様々な実装例があるようですが、
WebMvcConfigurer インターフェースを実装した、慣習的に WebMvcConfig という名前のクラスを作ることが多いようです。
下記の例のように、チェックを適用するURLパターン、その中で除外するURLパターンを定義できます。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public LoginCheckInterceptor LoginCheckInterceptor() {
return new LoginCheckInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry
.addInterceptor(LoginCheckInterceptor())
.addPathPatterns("/STNP*") // チェック対象のURLパターン
/*.excludePathPatterns("/index", "/login")*/ // 除外したいパターンをここに書く
;
}
}
|
[3] エラーページの作成
先述の通り、エラーで弾いたら /denied というURLに遷移するInterceptorを作成したので、
それをハンドルするControllerクラスを作成します。
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import jakarta.servlet.http.HttpServletRequest;
@Controller
public class LoginErrorController implements ErrorController {
@RequestMapping("/denied")
@ResponseBody
public String handleDenied(HttpServletRequest request) {
final String s =
"<html lang='ja'><body><h3>ログインしていません</h3>" +
"以下のいずれかが原因に考えられます。解決しない場合システム管理者にご連絡ください。" +
"<ul>" +
"<li>メニューシステムにログインせずにアクセスされました。</li>" +
"<li>前回画面操作から時間が経過したのでタイムアウトしました。</li>" +
"</ul>" +
"</body></html>";
return s;
}
}
|

(first uploaded 2024/08/19 last updated 2024/08/19, URANO398)
|