Как получить форму входа в Spring Security до того, как Spring ее получит? - PullRequest
5 голосов
/ 27 января 2012

У меня есть форма входа в Spring с именем пользователя и паролем, которая указывает на /myapp/j_spring_security_check.

Я надеюсь перехватить отправку формы, когда кто-то отправляет форму входа в систему до того, как Spring получит запрос.

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

Как я могу это сделать? Эффективным способом?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 27 января 2012

Вы можете сделать это, используя обычную функциональность Spring Security. Шаги:

  1. Реализация пользовательских WebAuthenticationDetailsSource и WebAuthenticationDetails. WebAuthenticationDetails захватит дополнительные поля формы, которые вы хотите проверить.

    Примечание: В Spring 3.0 вам необходимо использовать BeanPostProcessor для настройки WebAuthenticationDetailsSource в UsernamePasswordAuthenticationFilter. В Spring 3.1 вы можете сделать это непосредственно в конфигурации пространства имен <form-login>.

  2. Реализация пользовательского AuthenticationProvider и в authenticate() отметьте WebAuthenticationDetails, выдав AuthenticationException, если проверка не удалась. На странице входа проверьте это исключение.

Кроме того, вы можете создать Filter, который выполняет проверку, и добавить его перед фильтром Spring Security.

1 голос
/ 30 июня 2012

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

В конфигурации Spring:

<bean id="authFormDetailsPostProcessor" class="com.sefaira.authauth.AuthFormDetailsPostProcessor">
  <property name="formVarNames" value="terms_of_service_accepted"/>
</bean>

AuthFormDetailsPostProcessor.java:

public class AuthFormDetailsPostProcessor implements BeanPostProcessor {

    private String [] formVarNames;

    public void setFormVarNames (String formVarNames) { 
    this.formVarNames = formVarNames.split (",");
    }

    public static class Details extends WebAuthenticationDetails {

    private Map<String, String> map;

    public Details (HttpServletRequest request, String [] parameters) {
        super (request);

        this.map = new HashMap<String, String>();
        for (String parameter : parameters) {
        this.map.put (parameter.trim(), request.getParameter (parameter.trim()));
        }
    }

    public String get (String name) {
        return map.get(name);
    }
    }

    public Object postProcessAfterInitialization(Object bean, String name) {
        if (bean instanceof UsernamePasswordAuthenticationFilter) {
            ((UsernamePasswordAuthenticationFilter)bean).setAuthenticationDetailsSource(
                    new AuthenticationDetailsSource() {
                        public Object buildDetails(Object context) {

                if (formVarNames == null) {
                throw new RuntimeException ("AuthFormDetailsPostProcessor bean requires a formVarNames property, specifying a comma-delimited list of form vars to provide in the details object.");
                }

                return new Details ((HttpServletRequest) context, formVarNames);
                        }
                    });
        }
        return bean;
    }

    public Object postProcessBeforeInitialization(Object bean, String name) {
        return bean;
    }
}

Это пользовательский Аутентификатор, который его использует:

public class AuthServiceAuthenticator implements AuthenticationProvider {

   @Override
    public Authentication authenticate (Authentication authentication) throws AuthenticationException {

    String email = (String) authentication.getPrincipal();  
    String password = (String) authentication.getCredentials();

    AuthFormDetailsPostProcessor.Details details = (AuthFormDetailsPostProcessor.Details) authentication.getDetails();

    // see if they checked the terms_of_service checkbox        
    String termsOfServiceVar = details.get ("terms_of_service_accepted");
    boolean termsOfServiceAccepted = (termsOfServiceVar != null && termsOfServiceVar.equals ("on"));

        // ... do your custom authentication ...

        return authentication;  // or a new authentication object
    }

    @Override
    public boolean supports(Class<? extends Object> authentication) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...