utente Connettiti con ricordi-me funzionalità in primavera 3.1
-
25-10-2019 - |
Domanda
Attualmente il login gli utenti a livello di codice (come quando il login tramite Facebook o altri mezzi che usando il mio modulo di login) con:
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(user, "", authorities)
);
Quello che voglio fare, invece è accedere l'utente come se mettono l'opzione di ricordare-me nel form di login. Così sto indovinando ho bisogno di usare la RememberMeAuthenticationToken
al posto del UsernamePasswordAuthenticationToken
? Ma quello che faccio metto per l'argomento key
del costruttore?
RememberMeAuthenticationToken(String key, Object principal, Collection<? extends GrantedAuthority> authorities)
UPDATE : sto usando il Persistent Approach provvisorie descritte qui . Quindi non c'è una chiave come nel semplice Hash-Based Approach Token.
Soluzione
suppongo avete già impostato <remember-me>
nella configurazione.
Il modo ricordare-me funziona è imposta un cookie che è riconosciuto quando l'utente torna al sito dopo la sessione è scaduta.
Dovrai sottoclasse il RememberMeServices
(TokenBased
o PersistentTokenBased
) si sta utilizzando e rendere il pubblico onLoginSuccess (). Ad esempio:
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>
iniettare il RememberMeServices nel chicco di cui si sta facendo l'accesso programmatico. Quindi chiamare onLoginSuccess()
su di esso, utilizzando l'UsernamePasswordAuthenticationToken che si è creato. Che impostare il cookie.
UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken(user, "", authorities);
SecurityContextHolder.getContext().setAuthentication(auth);
getRememberMeServices().onLoginSuccess(request, response, auth);
Aggiorna
@at migliorato questo, senza sottoclassi di 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);
Altri suggerimenti
Questa è la fonte per il costruttore.
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);
}
La chiave viene assegnata e la sua utilizzato per determinare se l'autenticazione utilizzato per questo utente nel contesto di protezione non è una 'forgiato'.
Date un'occhiata alla fonte 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;
}
Quindi, per rispondere alla tua domanda, è necessario passare il codice hash del campo key
del Authentication
che rappresenta l'utente .