MVC Форма на основе Spring Security войти? - PullRequest
1 голос
/ 19 сентября 2011

У меня есть приложение, которое использует Spring Security для управления доступом к страницам, для управления ролями пользователей (GrantedAuthority) и для ACL. Приложение использует стандарт UsernamePasswordAuthenticationFilter, который перехватывает запросы к /j_spring_security_check (с параметрами запроса j_username и j_password), и, используя ProviderManager, проверяет подлинность пользователя и в случае успеха сохраняет его в SecurityContextHolder.

Вышеуказанное настроено в контексте безопасности с использованием настроенного UserDetailsService:

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref='myUserDetailsService'/>
</authentication-manager>

Приведенный выше подход в моем случае не является оптимальным по следующим причинам:

  • Для добавления капчи требуются дополнительные фильтры
  • Чтобы настроить логику входа в систему, мне также необходимо заменить AuthenticationProvider
  • показывать ошибки в форме входа в систему сложно, поскольку я не могу использовать формы Spring MVC

Моя идея - удалить вход в систему на основе перехватчика и поместить всю логику в контроллер Spring 3 MVC. Псевдокод выглядит следующим образом:

RequestMapping(value="/login/", method = RequestMethod.POST)
public String attemptLogin(HttpServletRequest request, HttpServletResponse response,
    @ModelAttribute("login") LoginCmd login, Model model) {

    // validate command (username, password, captcha)
    // ...

    // load user from DB
    User user = userService.loadUserByUsername(login.getUsername());

    // extra logic (check number of failed logins + other stuff)
    // ...

    // In case everything is fine, create a spring security User

    /* Instead of creating the user, read it from DB */
    org.springframework.security.core.userdetails.User authUser =
        new org.springframework.security.core.userdetails.User(
        login.getUsername() /*username*/,
        login.getPassword() /*password*/,
        true /*enabled*/,
        true /*accountNonExpired */,
        true /*credentialsNonExpired */,
        true /*accountNonLocked*/,
        new ArrayList<GrantedAuthority>() /*authorities*/
    );

    // build the AuthenticationToken
    UsernamePasswordAuthenticationToken authResult =
        new UsernamePasswordAuthenticationToken(authUser, login.getPassword(),
        authUser.getAuthorities());
    // use WebAuthenticationDetailsSource do build details
    authResult.setDetails(detailsSource.buildDetails(request));
    SecurityContextHolder.getContext().setAuthentication(authResult);

    return SUCCESS_VIEW;
}

Видите ли вы какие-либо проблемы с решением здесь выше? Достаточно ли установить аутентификацию внутри SecurityContextHolder? Я что-то упустил?

Комментарии и предложения приветствуются ;-) Большое спасибо всем Andrea

1 Ответ

0 голосов
/ 18 октября 2011

Я прошел код Spring Security, и при успешной аутентификации исходный код просто сохраняет объект Authentication в SecurityContextHolder, больше ничего не делается.

Например, в классе AbstractAuthenticationProcessingFilter (который используется стандартным входом в систему перехвата запросов на /j_spring_security_check):

 protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        Authentication authResult) throws IOException, ServletException {

    if (logger.isDebugEnabled()) {
        logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
    }

    SecurityContextHolder.getContext().setAuthentication(authResult);

    rememberMeServices.loginSuccess(request, response, authResult);

    // Fire event
    if (this.eventPublisher != null) {
        eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
    }

    successHandler.onAuthenticationSuccess(request, response, authResult);
}

Я реализовал это в своем приложении, и все работает нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...