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