1. 概要

Webサイトでは、ユーザーがすでにログインしているときにユーザーがログインにアクセスできないようにするのが一般的です。これを行う一般的な方法は、ユーザーを別のページ(通常はログイン後のアプリケーションの開始点)にリダイレクトすることです。 。

このチュートリアルでは、Springセキュリティを使用してこのソリューションを実装する複数の方法について説明します。

また、ログインをすばやく実装する方法の詳細については、この記事から始めることができます。

2. 認証検証

まず、認証を検証する方法が必要です。

つまり、 SecurityContextから認証の詳細を取得し、ユーザーがログインしているかどうかを確認する必要があります

private boolean isAuthenticated() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication == null || AnonymousAuthenticationToken.class.
      isAssignableFrom(authentication.getClass())) {
        return false;
    }
    return authentication.isAuthenticated();
}

これは、リダイレクトを担当する以下のすべてのコンポーネントで使用します。

3. ログインコントローラからのリダイレクト

目標を達成するための最も簡単な方法は、コントローラーのログインページのエンドポイントを定義することです。

また、ユーザーが認証されている場合は特定のページを返し、そうでない場合はログインページを返す必要があります。

@GetMapping("/loginUser")
public String getUserLoginPage() {
    if (isAuthenticated()) {
        return "redirect:userMainPage";
    }
    return "loginUser";
}

4. インターセプターの使用

ユーザーをリダイレクトする別の方法は、ログインページのURIのインターセプターを使用することです。

インターセプターは、要求がコントローラーに到着する前に要求をインターセプトします。 したがって、認証に基づいて、認証をさらに進めるか、ブロックしてリダイレクト応答を返すかを決定できます。

ユーザーが認証されている場合は、応答で2つのことを変更する必要があります。

  • ステータスコードをHttpStatus.SC_TEMPORARY_REDIRECTに設定します
  • LocationヘッダーとリダイレクトURLを追加します

そして最後に、 false を返すことにより、実行チェーンを中断します。

public class LoginPageInterceptor implements HandlerInterceptor {
    UrlPathHelper urlPathHelper = new UrlPathHelper();
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if ("/loginUser".equals(urlPathHelper.getLookupPathForRequest(request)) && isAuthenticated()) {
            String encodedRedirectURL = response.encodeRedirectURL(
              request.getContextPath() + "/userMainPage");
            response.setStatus(HttpStatus.SC_TEMPORARY_REDIRECT);
            response.setHeader("Location", encodedRedirectURL);

            return false;
        } else {
            return true;
        }
    }

    // isAuthenticated method 
}

また、SpringMVCライフサイクルにインターセプターを追加する必要があります。

@Configuration
public class LoginRedirectMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginPageInterceptor());
    }
}

SpringのXMLスキーマベースの構成を使用して、同じことを実現できます。

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/loginUser"/>
        <bean class="com.baeldung.loginredirect.LoginPageInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

5. フィルタの使用

同様に、Springフィルターを実装できます。

このフィルターは、Spring Securityのフィルターチェーンを使用して、SecurityContextに直接適用できます。 したがって、認証が作成された直後に要求をインターセプトできます。

GenericFilterBeanを拡張し、 doFilter メソッドをオーバーライドして、認証を確認しましょう。

public class LoginPageFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
        HttpServletRequest servletRequest = (HttpServletRequest) request;
        HttpServletResponse servletResponse = (HttpServletResponse) response;

        if (isAuthenticated() && "/loginUser".equals(servletRequest.getRequestURI())) {

            String encodedRedirectURL = ((HttpServletResponse) response).encodeRedirectURL(
              servletRequest.getContextPath() + "/userMainPage");

            servletResponse.setStatus(HttpStatus.SC_TEMPORARY_REDIRECT);
            servletResponse.setHeader("Location", encodedRedirectURL);
        }

        chain.doFilter(servletRequest, servletResponse);
    }
    // isAuthenticated method 
}

フィルタチェーンのUsernamePasswordAuthenticationFilterの後にフィルタを追加する必要があります。

さらに、ログインページURIのリクエストを承認して、そのフィルターチェーンを有効にする必要があります。

@Configuration
@EnableWebSecurity
public class LoginRedirectSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .addFilterAfter(new LoginPageFilter(), UsernamePasswordAuthenticationFilter.class)
          .authorizeRequests().antMatchers("/loginUser").permitAll()
           
        // Other security configuration
    }
}

最後に、XML構成を使用することを選択した場合、フィルターのBeanを定義し、それをセキュリティHTTPタグのフィルターチェーンに追加できます。

<beans:bean id="loginPageFilter" class="com.baeldung.loginredirect.LoginPageFilter"/>

<security:http pattern="/**" use-expressions="true" auto-config="true">
    <security:intercept-url pattern="/loginUser" access="permitAll"/>
    <security:custom-filter after="BASIC_AUTH_FILTER" ref="loginPageFilter"/>
</security:http>

Spring Securityのカスタムフィルターを作成する方法の簡単なチュートリアルは、ここにあります。

6. 結論

このチュートリアルでは、Springセキュリティを使用して、ログインページからすでにログインしているユーザーをリダイレクトする複数の方法について説明しました。

いつものように、このチュートリアルで使用される完全なソースコードは、GitHubから入手できます。

興味深いかもしれない別のチュートリアルは、 Spring Securityでログインした後に別のページにリダイレクトするです。このチュートリアルでは、さまざまなタイプのユーザーを特定のページにリダイレクトする方法を学びます。