Вход пользователя с помощью функции запомнить меня в Spring 3.1 - PullRequest
17 голосов
/ 18 октября 2011

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

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

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

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

ОБНОВЛЕНИЕ : я использую описанный подход Постоянный токенздесь .Таким образом, здесь нет ключа, подобного простому подходу на основе хэшей.

Ответы [ 2 ]

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

Я предполагаю, что в вашей конфигурации уже установлено <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 в компонент, где вы выполняете программный вход в систему. Затем вызовите onLoginSuccess() для него, используя UsernamePasswordAuthenticationToken, который вы создали. Это установит печенье.

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

UPDATE

@ улучшено, без подклассов 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 голосов
/ 18 октября 2011

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

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);
}

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

Посмотрите на источник 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, представляющего пользователя .

...