1. 개요

웹 사이트에서는 사용자가 이미 로그인 한 상태에서 로그인을 방문하지 못하도록 하는 것이 일반적 입니다. 이를 수행하는 일반적인 방법은 일반적으로 로그인 후 응용 프로그램의 시작 지점 인 다른 페이지로 사용자를 리디렉션하는 것입니다.

이 예제에서는 Spring Security를 ​​사용하여이 솔루션을 구현하는 여러 방법을 탐색합니다.

또한 로그인을 신속하게 구현하는 방법에 대해 자세히 알아 보려면 이 기사 부터 시작할 수 있습니다  .

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에서 인터셉터를 사용하는 것입니다.

인터셉터는 컨트롤러에 도착하기 전에 요청을 가로 챌 것입니다. 따라서 인증을 기반으로 더 멀리 놓거나 차단하고 리디렉션 응답을 반환할지 결정할 수 있습니다.

사용자가 인증 된 경우 응답에서 두 가지를 수정해야합니다.

  • 상태 코드를 HttpStatus.SC_TEMPORARY_REDIRECT로 설정합니다.
  • 리디렉션 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 
}

또한 Spring MVC 라이프 사이클에 인터셉터를 추가해야합니다 .

@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 구성을 사용하기로 선택하면 필터에 대한 빈을 정의하고 Security 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 Security를 ​​사용하여 로그인 페이지에서 이미 로그인 한 사용자를 리디렉션하는 여러 방법을 탐색했습니다.

항상 그렇듯이이 사용방법(예제)에서 사용 된 전체 소스 코드는 GitHub에서 사용할 수 있습니다 .

관심을 가질만한 또 다른 예제은 Redirect to Different Pages after Login with Spring Security 입니다. 여기서는 다른 유형의 사용자를 특정 페이지로 리디렉션하는 방법을 배웁니다.