Подтвердить что ты не робот

Войдите в систему с функцией mem-me в Spring 3.1

В настоящее время я регистрирую пользователей программно (например, когда они подключаются к Facebook или другим способом, кроме использования моей формы входа):

SecurityContextHolder.getContext().setAuthentication(
  new UsernamePasswordAuthenticationToken(user, "", authorities)
);

Вместо этого я хочу войти в систему, как если бы они установили параметр "Запомнить меня" в форме входа. Поэтому я предполагаю, что мне нужно использовать RememberMeAuthenticationToken вместо UsernamePasswordAuthenticationToken? Но что я положил для аргумента key конструктора?

RememberMeAuthenticationToken(String key, Object principal, Collection<? extends GrantedAuthority> authorities) 

UPDATE. Я использую Persistent Token Approach, описанный здесь. Таким образом, нет никакого ключа, как в методе Token Approach на основе простого хаша.

4b9b3361

Ответ 1

Я предполагаю, что у вас уже есть <remember-me> в вашей конфигурации.

Как помню, как работает, он устанавливает cookie, который распознается, когда пользователь возвращается на сайт после истечения срока их сеанса.

Вам нужно подклассифицировать RememberMeServices (TokenBased или PersistentTokenBased), который вы используете, и сделать onLoginSuccess() общедоступным. Например:

public class MyTokenBasedRememberMeServices extends PersistentTokenBasedRememberMeServices {
    @Override
    public void onLoginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication) {
        super.onLoginSuccess(request, response, successfulAuthentication);
    }   
} 

<remember-me services-ref="rememberMeServices"/>

<bean id="rememberMeServices" class="foo.MyTokenBasedRememberMeServices">
    <property name="userDetailsService" ref="myUserDetailsService"/>
    <!-- etc -->
</bean>

Внесите свои функции RememberMeServices в bean, где вы выполняете вход в систему. Затем наберите onLoginSuccess(), используя созданный вами UsernamePasswordAuthenticationToken. Это установит файл cookie.

UsernamePasswordAuthenticationToken auth = 
    new UsernamePasswordAuthenticationToken(user, "", authorities);
SecurityContextHolder.getContext().setAuthentication(auth);
getRememberMeServices().onLoginSuccess(request, response, auth);  

UPDATE

@at улучшилось, без подкласса RememberMeServices:

UsernamePasswordAuthenticationToken auth = 
    new UsernamePasswordAuthenticationToken(user, "", authorities);
SecurityContextHolder.getContext().setAuthentication(auth);

// This wrapper is important, it causes the RememberMeService to see
// "true" for the "_spring_security_remember_me" parameter.
HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request) {
    @Override public String getParameter(String name) { return "true"; }            
};

getRememberMeServices().loginSuccess(wrapper, response, auth);  

Ответ 2

Это источник для конструктора.

public RememberMeAuthenticationToken(String key, Object principal, Collection<? extends GrantedAuthority> authorities) {
    super(authorities);

    if ((key == null) || ("".equals(key)) || (principal == null) || "".equals(principal)) {
        throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
    }

    this.keyHash = key.hashCode();
    this.principal = principal;
    setAuthenticated(true);
}

Ключ hashed и используется для определения того, является ли аутентификация, используемая для этого пользователя в контексте безопасности, не "поддельной".

Посмотрите на источник RememberMeAuthenicationProvider.

public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    if (!supports(authentication.getClass())) {
        return null;
    }

    if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication).getKeyHash()) {
        throw new BadCredentialsException(messages.getMessage("RememberMeAuthenticationProvider.incorrectKey",
                "The presented RememberMeAuthenticationToken does not contain the expected key"));
    }

    return authentication;
}

Чтобы ответить на ваш вопрос, вам нужно передать хэш-код поля key Authentication, представляющего пользователя.