Перейти к основному содержимому

Перенаправление вошедших в систему пользователей с помощью Spring Security

· 4 мин. чтения

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.
  • Добавьте заголовок 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
}

Нам также нужно добавить перехватчик в жизненный цикл 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.foreach.loginredirect.LoginPageInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

5. Использование фильтра

Точно так же мы можем реализовать фильтр Spring.

Фильтр можно напрямую применить к SecurityContext , используя цепочку фильтров Spring Security. Таким образом, он может перехватить запрос сразу после создания аутентификации.

Давайте расширим 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.foreach.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 .

Другой учебник, который может представлять интерес, — « Перенаправление на разные страницы после входа в систему с помощью Spring Security », в котором мы узнаем, как перенаправлять пользователей разных типов на определенные страницы.