Перенаправление на разные страницы после входа в Spring Security

Перенаправление на разные страницы после входа в Spring Security

1. обзор

Общее требование к веб-приложению -redirect different types of users to different pages after login. Примером этого может быть перенаправление стандартных пользователей на страницу/homepage.html и пользователей с правами администратора, например, на страницу/console.html.

В этой статье будет показано, как быстро и безопасно реализовать этот механизм с помощью Spring Security. Статья также строится на основеSpring MVC tutorial, который касается настройки основных компонентов MVC, необходимых для проекта.

2. Конфигурация безопасности Spring

Spring Security предоставляет компонент, который несет прямую ответственность за решение, что делать после успешной аутентификации -AuthenticationSuccessHandler.

Давайте посмотрим, как мы можем настроить это в классе@Configuration:

@Configuration
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean("authenticationManager")
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // @formatter:off
        auth.inMemoryAuthentication()
            .withUser("user1").password("{noop}user1Pass").roles("USER")
            .and()
            .withUser("admin1").password("{noop}admin1Pass").roles("ADMIN");
        // @formatter:on
    }

    @Bean
    public AuthenticationSuccessHandler myAuthenticationSuccessHandler(){
        return new MySimpleUrlAuthenticationSuccessHandler();
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/anonymous*").anonymous()
            .antMatchers("/login*").permitAll()
            .anyRequest().authenticated()

            .and()
            .formLogin()
            .loginPage("/login.html")
            .loginProcessingUrl("/login")
            .successHandler(myAuthenticationSuccessHandler())
            // ...
    }
}

Части этой конфигурации, на которых следует сосредоточиться, - это определение the custom authentication success handler bean and using the successHandler() method to add the bean to the security configuration.

Остальная часть конфигурации довольно стандартна: единственный простой элементhttp, защищающий все и разрешающий только неаутентифицированный доступ к/login*, и стандартный провайдер аутентификации в памяти для простоты.

И эквивалентная конфигурация xml:


    
    

    
    





    
        
            
            
        
    

3. Пользовательский обработчик успешной аутентификации

Помимо интерфейсаAuthenticationSuccessHandler, Spring также предоставляет разумное значение по умолчанию для этого компонента стратегии -AbstractAuthenticationTargetUrlRequestHandler и простую реализацию -SimpleUrlAuthenticationSuccessHandler. Обычно эти реализации определяют URL-адрес после входа в систему и выполняют перенаправление на этот URL-адрес.

Несмотря на свою гибкость, механизм определения этого целевого URL не позволяет определять его программно, поэтому мы собираемся реализовать интерфейс и предоставить индивидуальную реализацию обработчика успеха. This implementation is going to determine the URL to redirect the user to after login based on the role of the user:с

public class MySimpleUrlAuthenticationSuccessHandler
  implements AuthenticationSuccessHandler {

    protected Log logger = LogFactory.getLog(this.getClass());

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
      HttpServletResponse response, Authentication authentication)
      throws IOException {

        handle(request, response, authentication);
        clearAuthenticationAttributes(request);
    }

    protected void handle(HttpServletRequest request,
      HttpServletResponse response, Authentication authentication)
      throws IOException {

        String targetUrl = determineTargetUrl(authentication);

        if (response.isCommitted()) {
            logger.debug(
              "Response has already been committed. Unable to redirect to "
              + targetUrl);
            return;
        }

        redirectStrategy.sendRedirect(request, response, targetUrl);
    }

    protected String determineTargetUrl(Authentication authentication) {
        boolean isUser = false;
        boolean isAdmin = false;
        Collection authorities
         = authentication.getAuthorities();
        for (GrantedAuthority grantedAuthority : authorities) {
            if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
                isUser = true;
                break;
            } else if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
                isAdmin = true;
                break;
            }
        }

        if (isUser) {
            return "/homepage.html";
        } else if (isAdmin) {
            return "/console.html";
        } else {
            throw new IllegalStateException();
        }
    }

    protected void clearAuthenticationAttributes(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null) {
            return;
        }
        session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
    }

    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
    }
    protected RedirectStrategy getRedirectStrategy() {
        return redirectStrategy;
    }
}

determineTargetUrl - это ядро ​​стратегии - просто смотрит на тип пользователя (определяемый полномочным органом) иpicks the target URL based on this role.

Таким образом,admin user, определяемый полномочиямиROLE_ADMIN, будет перенаправлен на страницу консоли после входа в систему, аthe standard user - как определеноROLE_USER - будет перенаправлен на страницу консоли. домашняя страница.

4. Заключение

Как всегда, доступен код, представленный в этой статьеover on Github. Это проект, основанный на Maven, поэтому его легко импортировать и запускать как есть.