Специальный вход с Spring Security - PullRequest
16 голосов
/ 21 июля 2011

Компания, в которой я сейчас работаю, имеет особый вид аутентификации.

Действительно, несколько пользователей могут иметь одинаковые логин и пароль. Таким образом, чтобы идентифицировать их, во второй раз, пользователь должен дать свою электронную почту. Но опять же, в некоторых случаях это может беспокоить нескольких пользователей, а затем пользователь должен предоставить идентификатор своей компании для полной аутентификации.

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

Итак, мой вопрос: как проще всего реализовать в Spring Security этот специальный процесс входа в систему ?

Заранее спасибо.

1 Ответ

16 голосов
/ 22 июля 2011

Мне пришлось сделать аналогичный двухэтапный процесс аутентификации.Это звучит просто, но найти правильные места для инъекций и правильные методы переопределения было нелегко.Основная идея состоит в том, чтобы предоставить другую роль для промежуточной аутентификации (проверка электронной почты), а затем предоставить полный доступ после подтверждения электронной почты.

Надеемся, что приведенный ниже код дает некоторые полезные советы о том, как это можно решить для вашегосценарий.

Создайте пользовательский UserDetailsChecker для обработки проверок после проверки подлинности.Здесь определяется роль пользователя.

public class CustomPostAuthenticationChecks implements UserDetailsChecker {

        public void check(UserDetails userDetails) {

            CustomUser customUser = (CustomUser) userDetails;
            if (customUser.needsEmailAuthentication()) {
                // Get rid of any authorities the user currently has
                userDetails.getAuthorities().clear();
                // Set the new authority, only allowing access to the 
                // email authentication page.
                userDetails.getAuthorities().add(new GrantedAuthorityImpl("ROLE_NEEDS_EMAIL_AUTH"));
            } else {
                userDetails.getAuthorities().add(new GrantedAuthorityImpl("ROLE_AUTHORIZED_USER"));
            }
    }

Создайте пользовательский AuthenticationSuccessHandler.Этот класс отправляет пользователя на правильный URL-адрес в зависимости от его роли.

public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

@Override
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {

    String targetUrl = null;

    SecurityContext securityContext = SecurityContextHolder.getContext();

    Collection<GrantedAuthority> authorities = securityContext.getAuthentication().getAuthorities();

    if (authorities.contains(new GrantedAuthorityImpl("ROLE_NEEDS_EMAIL_AUTH"))) {
        targetUrl = "/authenticate";
    } else if (authorities.contains(new GrantedAuthorityImpl("ROLE_AUTHORIZED_USER"))) {
        targetUrl = "/authorized_user_url";
    } else {
        targetUrl = super.determineTargetUrl(request, response);
    }

    return targetUrl;
}

После аутентификации адреса электронной почты пользователя вам необходимо предоставить пользователю полный доступ к приложению:

public void grantUserAccess(User user) {
    SecurityContext securityContext = SecurityContextHolder.getContext();
    Authentication auth = securityContext.getAuthentication();
    user.getAuthorities().clear();
    user.getAuthorities().add(new GrantedAuthorityImpl("ROLE_AUTHORIZED_USER"));
    Authentication newAuth = new UsernamePasswordAuthenticationToken(user, auth.getCredentials(), user.getAuthorities());
    securityContext.setAuthentication(newAuth);
}

Определите пользовательский поставщик аутентификации для регистрации ваших CustomPostAuthenticationChecks:

<security:authentication-manager>
    <security:authentication-provider ref="customAuthenticationProvider" />
</security:authentication-manager>

<bean id="customAuthenticationProvider" class="YourAuthenticationProvider">
    <property name="postAuthenticationChecks">
        <bean class="CustomPostAuthenticationChecks"/>
    </property>
</bean>

Если вы используете стандартный тег входа в форму, вы можете легко определить свой пользовательский AuthenticationSuccessHandler:

<security:form-login authentication-success-handler-ref="customAuthenticationSuccessHandler">

...

<bean id="customAuthenticationSuccessHandler" class="CustomAuthenticationSuccessHandler"/>

Добавьте новое правило перехвата роли для / authenticate URL, чтобы только пользователи, которым требуется дополнительная аутентификация, могли получить доступ к этой странице.

<security:intercept-url pattern="/authenticate/**" access="hasRole('ROLE_NEEDS_EMAIL_AUTH')" />
<security:intercept-url pattern="/authorized_user_url/**" access="hasRole('ROLE_AUTHORIZED_USER')" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...